我有一个脚本,我希望在通过shell运行时在某些点上暂停,但在命令行运行时不暂停。我在SO上看到了一个类似的问题,但由于两个原因无法使用相同的解决方案:首先,是否暂停需要依赖于多个因素,其中只有一个是是否双击。其次,我将向团队中的其他人分发此脚本,而我无法现实地要求他们进行会影响所有脚本的注册表更改。
这可能吗?
找到了 :-) - 在拼命思考当交互运行时cmd
可能会做什么,但是直接启动批处理文件时不会做什么...最终我终于找到了。
伪变量%cmdcmdline%
包含用于启动cmd
的命令行。如果cmd
正常启动,则其中包含类似以下内容的内容:
"C:\Windows\System32\cmd.exe"
但是,当启动批处理文件时,它看起来像这样:
cmd /c ""C:\Users\Me\test.cmd" "
小型演示:
@echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1
if defined DOUBLECLICKED pause
这种检查方式可能并不是最健壮的,但是如果批处理文件是直接启动的,则/c
参数应该只出现在参数中。
在Windows 7 x64上进行了测试。它可能会起作用,也可能无法正常工作、出现奇怪的问题、吃掉孩子(这可能是件好事)或咬你的鼻子。
%0
的事情,但很遗憾它会出错。当我通过for
运行%cmdcmdline%
时,由于我的主目录包含空格并且命令行有双引号,因此批处理文件的路径和名称被分成两个标记,这使得for
无法正常工作。另一个选择可能是使用echo.%cmdcmdline%|findstr /i /c:"%~0" >nul 2>&1 && set DOUBLECLICKED=1
(或者也许是||
,我总是在findstr
上犯错误),这实际上会搜索%0
而不是依赖于标记化。但如果批处理文件是由另一个批处理文件调用的话,它仍然会失败。 - Joey/C
作为参数传递给资源管理器。这将执行一个不区分大小写的比较:for %%x in (%CMDCMDLINE%) do if /I [%%~x] equ [/c] pause
。 - indivcmd /c
。 - Ruben Bartelinkcmd
的其他程序调用将使用cmd /c
(无论如何都必须这样)。这是不可避免的,因为毕竟cmd
可能是唯一一个可以解释批处理文件而不委派给另一个程序的程序。 - Joey:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
编辑:可以使用一行代码完成相同的操作:
echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1
通俗易懂地说,这段代码会将%cmdcmdline%
的值传递给findstr,然后在其中搜索当前脚本名称。如果shift
之前没有被调用,%0
将包含当前脚本名称。%~nx0
从%0
中提取文件名和扩展名。通过将输出重定向到NUL,>NUL 2>&1
可以使findstr变为静音状态。如果findstr无法找到所需的子字符串,则设置非零错误级别。&&
只有在前一个命令返回而没有出错时才执行。因此,如果从命令行启动脚本,则standalone
不会被定义。
稍后在脚本中我们可以这样做:
if defined standalone pause
ECHO %cmdcmdline% | findstr /i /c:"%~nx0" >NUL 2>&1 && PAUSE
- 不需要变量。 - EM0@set nested=%nested%Z
AUTOEXEC.NT
完全被忽略,AUTOEXEC.BAT
只在系统启动时执行一次,并且 AutoRun 注册表键每个 CMD.EXE
会话只执行一次,无论它是如何启动的。 - Ben Blankcmd
进程中启动。因此,如果我只是启动一个 cmd
实例并从那里启动批处理文件,则 nested
将为 Z
。否则,这是检测嵌套 shell 的好方法,但不适用于批处理文件。 - Joeyautoexec.nt
从未存储在驱动器的根目录中,而是位于 %systemroot%\system32
目录下。据我所知,它只会影响 command.com
,而不会影响 cmd
。 - Joey更多信息...
我从一个包含以下内容的批处理文件(test.cmd)开始:
@echo %cmdcmdline%
cmd /c ""D:\Path\test.cmd" "
在命令提示符窗口中执行“test.cmd”批处理文件时,echo %cmdcmdline% 的显示取决于命令窗口的启动方式...
如果我通过单击“开始”按钮和“命令提示符”来启动“cmd.exe”,或者从搜索/运行框中执行“cmd.exe”,然后执行“test.cmd”批处理文件,则 echo %cmdcmdline% 的显示为:
"C:\Windows\system32\cmd.exe"
"C:\Windows\system32\cmd.exe"
但是,如果我在Windows资源管理器窗口内“右键单击”,然后选择“在此处打开命令提示符”,然后执行“test.cmd”批处理文件,那么echo %cmdcmdline%的显示结果为:
"C:\Windows\System32\cmd.exe" /k ver
所以,如果你从一个包含“/c”字符的快捷方式中启动“cmd.exe”,那么前面示例中的测试将无法正确测试此情况。因此,请小心处理。