Joe*_*ite 29 windows command-prompt
Windows命令提示符(cmd.exe)有一个可选/s参数,它修改/c(运行特定命令然后退出)或/k(运行特定命令然后显示shell提示符)的行为.这个/s参数显然与某些神秘的引用处理有关.
文档令人困惑,但据我所知,当你这样做cmd /csomething,并且something包含引号时,默认情况下cmd有时会删除这些引号,并/s告诉它不要管它们.
我不明白的是,当引用删除会破坏任何东西,因为这是唯一的时间/s("抑制默认的引用删除行为")是必要的.它只删除某些神秘条件下的引号,其中一个条件是/c必须是引号之后的第一个字符.因此,它不会删除参数周围的引号; 它要么删除你正在运行的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我不知所措?什么时候有必要?什么时候会有什么不同?
Ben*_*Ben 17
Cmd/S非常有用,因为它可以节省您不必担心"引用引号".回想一下,该/C参数意味着"执行此命令,就像我在提示符下键入它一样,然后退出".
因此,如果您有一个复杂的命令要传递给CMD.exe,您必须记住CMD的参数引用规则,并正确地转义所有引号或使用/S,这会触发一个特殊的非解析规则"Strip first and最后"并将所有其他字符视为执行未更改的命令".
您可以在想要利用CMD shell功能的地方使用它,而不是直接调用另一个程序.例如环境变量扩展,输出或输入重定向,或使用CMD.exe内置函数.
例:
使用内置的shell:如果您DEL /Q/S "%TMP%\TestFile"在提示符下键入,则执行:
CMD.exe /S /C " DEL /Q/S "%TMP%\TestFile" "
Run Code Online (Sandbox Code Playgroud)
这会执行SomeCommand.exe将标准输出重定向到临时文件并将标准错误重定向到同一位置:
CMD.exe /S /C " "%UserProfile%\SomeCommand.exe" > "%TMP%\TestOutput.txt" 2>&1 "
Run Code Online (Sandbox Code Playgroud)
那么什么/S能给你额外的?主要是它使您免于担心引用引号.如果您不确定例如环境变量是否包含引号字符,它也会有所帮助.只需说出/S并在开头和结尾添加额外的报价.
隐约相关:Bourne Shell中的$*.
一些背景
回想一下main()的参数列表是C-ism和Unix-ism.Unix/Linux shell(例如Bourne Shell等)解释命令行,取消引用参数,将通配符扩展*为文件列表,并将参数列表传递给被调用程序.
所以,如果你说:
$ vi *.txt
Run Code Online (Sandbox Code Playgroud)
vi命令可以看到例如这些参数:
vi
a.txt
b.txt
c.txt
d.txt
Run Code Online (Sandbox Code Playgroud)
这是因为unix/linux在"参数列表"的基础上在内部运行.
最终从CP/M和VAX派生的Windows在内部不使用此系统.对于操作系统,命令行只是一个字符串.被调用程序负责解释命令行,扩展文件globs(*等)并处理不引用的引用参数.
因此,C期望的参数必须被C运行时库破解.操作系统只提供带有参数的单个字符串,如果您的语言不是C(或者即使它是),它可能不会被解释为根据shell规则引用的空格分隔的参数,而是完全不同的东西.
Har*_*ton 10
这是一个如何产生影响的例子.
假设您有两个可执行文件:c:\Program.exe和c:\Program Files\foo.exe.
如果你说
cmd /c "c:\Program Files\foo"
Run Code Online (Sandbox Code Playgroud)
foo.exe如果你说,你会跑(没有参数)
cmd /s /c "c:\Program Files\foo"
Run Code Online (Sandbox Code Playgroud)
你会碰到Program.exe与Files\foo作为参数.
(奇怪的是,在第一个例子中,如果foo.exe不存在,Program.exe则会运行.)
附录:如果你要打字
c:\Program Files\foo
Run Code Online (Sandbox Code Playgroud)
在命令提示符下,您将运行Program.exe(与cmd/s/c一样)而不是foo.exe(与cmd/c一样).因此,如果要确保以与在命 在Michael Burr链接的问题中,这可能更有可能是需要的,其中cmd.exe由CreateProcess启动,而不是从批处理文件或命令行本身启动.
也就是说,如果你说
CreateProcess("cmd.exe", "cmd /s /c \"" MY_COMMAND "\"", ...)
Run Code Online (Sandbox Code Playgroud)
然后,字符串MY_COMMAND将被解析,就像在命令提示符下键入一样.如果您正在从用户那里获取命令行输入,或者如果您正在处理应用程序提供的命令行,那么这可能是一个好主意.例如,C运行时库system()函数可能以这种方式实现.
| 归档时间: |
|
| 查看次数: |
70599 次 |
| 最近记录: |