什么是`cmd / s`?

时间:2012-03-26 05:20:01

标签: windows command-prompt

Windows命令提示符(cmd.exe)有一个可选的/s parameter,用于修改/c(运行特定命令然后退出)或/k(运行)的行为一个特定的命令,然后显示一个shell提示符)。这个/s参数显然与某些神秘的引用处理有关。

The docs令人困惑,但据我所知,当您执行cmd /c something something包含引号,默认情况下cmd有时会删除这些引号,/s会告诉它不要让它们单独使用。

我不明白的是,当引用删除会破坏任何内容时,因为这是唯一需要/s(“禁止默认引用删除行为”)的时间。它只删除某些神奇条件下的引号,其中一个条件是/c后面的第一个字符必须是引号。因此,它不会删除参数周围的引号;它要么删除正在运行的EXE路径周围的引号,要么删除整个命令行周围的引号(或者可能在命令行的前半部分周围,这将是奇怪的。)

  • 如果引用了EXE的路径,例如cmd /c "c:\tools\foo.exe" arg1 arg2,然后引号是不必要的,如果cmd想删除它们,那很好。 (如果路径在名称中有空格,它将不会删除它们 - 这是另一个神秘规则。)我无法想象有任何理由抑制引用删除,因此/s似乎没必要。
  • 如果引用整个命令行,例如cmd /c "foo.exe arg1 arg2",然后似乎删除引号是必要的,因为系统上没有名为foo.exe arg1 arg2的EXE;所以看起来选择退出引用删除使用/s实际上会破坏事情。 (实际上,它不会破坏事物:cmd /s /c "foo.exe arg1 arg2"可以正常工作。)

/s是否有一些微妙的东西在逃避我?什么时候有必要?什么时候会有什么不同?

2 个答案:

答案 0 :(得分:16)

Cmd / S非常有用,因为它可以节省您不必担心“引用引号”。回想一下,/C参数意味着“执行此命令,就像我在提示符下键入它一样,然后退出”。

因此,如果您有一个复杂的命令要传递给CMD.exe,您必须记住CMD的参数引用规则,并正确地转义所有引号,或使用/S,这会触发特殊的非-darsing rule“Strip first and last "并将所有其他字符视为执行不变的命令”。

您可以在想要利用CMD shell功能的地方使用它,而不是直接调用另一个程序。例如,环境变量扩展,输出或输入重定向,或使用CMD.exe内置插件。

示例:

使用内置shell:如果您在提示符下键入DEL /Q/S "%TMP%\TestFile",则执行此操作:

CMD.exe /S /C " DEL /Q/S "%TMP%\TestFile" "

这会执行SomeCommand.exe将标准输出重定向到临时文件并将标准错误重定向到同一位置:

CMD.exe /S /C " "%UserProfile%\SomeCommand.exe" > "%TMP%\TestOutput.txt" 2>&1 "

那么/S给你额外的东西是什么?主要是它使您免于担心引用引号。如果您不确定例如环境变量是否包含引号字符,它也会有所帮助。只需说出/S并在开头和结尾添加一个额外的引用。

模糊相关:Bourne Shell中的$ *。

一些背景

回想一下main()的参数列表是C-ism和Unix-ism。 Unix / Linux shell(例如Bourne Shell等)解释命令行,取消引用参数,将*之类的通配符扩展到文件列表,并将参数列表传递给被调用程序。

所以,如果你说:

$ vi *.txt

vi命令可以看到这些参数:

vi
a.txt
b.txt
c.txt
d.txt

这是因为unix / linux在“参数列表”的基础上在内部运行。

最终从CP / M和VAX派生的Windows在内部不使用此系统。对于操作系统,命令行只是一个字符串。被调用程序负责解释命令行,展开文件globs(*等)并处理不引用的引用参数。

所以C期望的参数必须被C运行时库破解。操作系统只提供带有参数的单个字符串,如果您的语言不是C(或者即使它是),它可能不会被解释为根据shell规则引用的空格分隔的参数,而是完全不同的东西。 / p>

答案 1 :(得分:10)

这是一个如何产生影响的例子。

假设您有两个可执行文件:c:\Program.exec:\Program Files\foo.exe

如果你说

cmd /c "c:\Program Files\foo"

你将运行foo.exe(没有参数),如果你说

cmd /s /c "c:\Program Files\foo"

您将以Program.exe作为参数运行Files\foo

(奇怪的是,在第一个示例中,如果foo.exe不存在,则Program.exe将会运行。)

附录: 如果您要输入

 c:\Program Files\foo

在命令提示符下,您将运行Program.exe(与cmd / s / c一样)而不是foo.exe(与cmd / c一样)。因此,如果要确保以与在命在Michael Burr链接的问题中,这可能更有可能是需要的,其中cmd.exe由CreateProcess而不是批处理文件或命令行本身启动。

也就是说,如果你说

CreateProcess("cmd.exe", "cmd /s /c \"" MY_COMMAND "\"", ...)

然后将解析字符串MY_COMMAND,就像在命令提示符下键入它一样。如果您正在从用户那里获取命令行输入,或者您正在处理应用程序提供的命令行,那么这可能是一个好主意。例如,C运行时库system()函数可能以这种方式实现。