windows 什么是“cmd /s”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9866962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is `cmd /s` for?
提问by Joe White
The Windows command prompt (cmd.exe
) has an optional /s
parameter, which modifies the behavior of /c
(run a particular command and then exit) or /k
(run a particular command and then show a shell prompt). This /s
parameter evidently has something to do with some arcane quote handling.
Windows 命令提示符 ( cmd.exe
) 有一个可选/s
参数,它可以修改/c
(运行特定命令然后退出)或/k
(运行特定命令然后显示 shell 提示符)的行为。这个/s
参数显然与一些神秘的报价处理有关。
The docsare confusing, but as far as I can tell, when you do cmd /c
something
, and the something
contains quotation marks, then by default cmd
will sometimes strip off those quotes, and /s
tells it to leave them alone.
文档令人困惑,但据我所知,当你这样做时cmd /c
something
,something
包含引号,然后默认情况下cmd
有时会去掉这些引号,并/s
告诉它不要管它们。
What I don't understand is when the quote removal would break anything, because that's the only time /s
("suppress the default quote-removal behavior") would be necessary. It only removes quotes under a certain arcane set of conditions, and one of those conditions is that the first character after the /c
must be a quotation mark. So it's not removing quotes around arguments; it's either removing quotes around the path to the EXE you're running, or around the entire command line (or possibly around the first half of the command line, which would be bizarre).
我不明白的是,引用删除何时会破坏任何内容,因为这是唯一需要的时间/s
(“抑制默认引用删除行为”)。它仅在一组特定的神秘条件下删除引号,其中一个条件是 之后的第一个字符/c
必须是引号。所以它不会删除参数周围的引号;它要么删除您正在运行的 EXE 路径周围的引号,要么删除整个命令行周围的引号(或者可能是命令行的前半部分,这很奇怪)。
- If the path to the EXE is quoted, e.g.
cmd /c "c:\tools\foo.exe" arg1 arg2
, then quotes are unnecessary, and ifcmd
wants to remove them, fine. (It won't remove them if the path has a space in the name -- that's another of the arcane rules.) I can't imagine any reason to suppress the quote removal, so/s
seems unnecessary. - If the entire command line is quoted, e.g.
cmd /c "foo.exe arg1 arg2"
, then it seems like quote removal would be a necessity, since there's no EXE namedfoo.exe arg1 arg2
on the system; so it seems like opting out of quote removal using/s
would actually break things. (In actual fact, however, it does not break things:cmd /s /c "foo.exe arg1 arg2"
works just fine.)
- 如果引用了 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"
工作得很好。)
Is there some subtlety to /s
that's eluding me? When would it ever be necessary? When would it even make any difference?
有什么微妙之处让/s
我望而却步吗?什么时候需要?它什么时候会有所作为?
回答by Ben
Cmd /S is very useful as it saves you having to worry about "quoting quotes". Recall that the /C
argument means "execute this command as if I had typed it at the prompt, then quit".
Cmd /S 非常有用,因为它使您不必担心“引用引号”。回想一下,该/C
参数的意思是“执行此命令,就像我在提示符下键入它一样,然后退出”。
So if you have a complicated command which you want to pass to CMD.exe you either have to remember CMD's argument quoting rules, and properly escape all of the quotes, or use /S
, which triggers a special non-parsing rule of "Strip first and last "
and treat all other characters as the command to execute unchanged".
因此,如果您有一个复杂的命令要传递给 CMD.exe,您要么必须记住 CMD 的参数引用规则,并正确地转义所有引号,要么使用/S
,这会触发“先剥离并删除”的特殊非解析规则最后"
并将所有其他字符视为命令执行不变”。
You would use it where you want to take advantage of the capabilities of the CMD shell, rather than directly calling another program. For example environment variable expansion, output or input redirection, or using CMD.exe built-ins.
您可以在想要利用 CMD shell 功能的地方使用它,而不是直接调用另一个程序。例如环境变量扩展、输出或输入重定向,或使用 CMD.exe 内置程序。
Example:
例子:
Use a shell built-in: This executes as-if you had typed DEL /Q/S "%TMP%\TestFile"
at the prompt:
使用内置的 shell:这就像您DEL /Q/S "%TMP%\TestFile"
在提示符下键入一样执行:
CMD.exe /S /C " DEL /Q/S "%TMP%\TestFile" "
This executes SomeCommand.exe redirecting standard output to a temp file and standard error to the same place:
这将执行 SomeCommand.exe 将标准输出重定向到临时文件并将标准错误重定向到同一位置:
CMD.exe /S /C " "%UserProfile%\SomeCommand.exe" > "%TMP%\TestOutput.txt" 2>&1 "
So what does /S
give you extra? Mainly it saves you from having to worry about quoting the quotes. It also helps where you are unsure whether for example an environtment variable contains quote characters. Just say /S
and put an extra quote at the beginning and end.
那么什么/S
能给你额外的好处呢?主要是它使您不必担心引用引号。它也有助于您不确定例如环境变量是否包含引号字符。只需说/S
并在开头和结尾加上额外的引用即可。
Vaguely Related: $* in Bourne Shell.
隐约相关:Bourne Shell 中的 $*。
Some background
一些背景
Recall that the list of arguments to main() is a C-ism and Unix-ism. The Unix/Linux shell (e.g. Bourne Shell etc) interprets the command line, un-quotes the arguments, expands wildcards like *
to lists of files, and passes a list of arguments to the called program.
回想一下 main() 的参数列表是 C-ism 和 Unix-ism。Unix/Linux shell(例如 Bourne Shell 等)解释命令行,取消引用参数,将通配符扩展*
为文件列表,并将参数列表传递给被调用的程序。
So if you say:
所以如果你说:
$ vi *.txt
The vi command sees for example these arguments:
例如,vi 命令可以看到这些参数:
vi
a.txt
b.txt
c.txt
d.txt
This is because unix/linux operates internally on the basis of "list of arguments".
这是因为 unix/linux 根据“参数列表”在内部运行。
Windows, which derives ultimately from CP/M and VAX, does not use this system internally. To the operating system, the command line is just a single string of characters. It is the responsibility of the called program to interpret the command line, expand file globs (*
etc) and deal with unquoting quoted arguments.
最终衍生自 CP/M 和 VAX 的 Windows 在内部不使用该系统。对于操作系统来说,命令行只是一个字符串。被调用程序负责解释命令行、扩展文件 globs(*
等)并处理未引用的引用参数。
So the arguments expected by C, have to be hacked up by the C runtime library. The operating system only supplies a single string with the arguments in, and if your language is not C (or even if it is) it may not be interpreted as space-separated arguments quoted according to shell rules, but as something completely different.
所以 C 期望的参数必须被 C 运行时库修改。操作系统只提供一个带有参数的字符串,如果你的语言不是 C(或者即使是),它可能不会被解释为根据 shell 规则引用的空格分隔参数,而是完全不同的东西。
回答by Harry Johnston
Here's an example of how it can make a difference.
以下是它如何发挥作用的示例。
Suppose you have two executables: c:\Program.exe
and c:\Program Files\foo.exe
.
假设您有两个可执行文件:c:\Program.exe
和c:\Program Files\foo.exe
.
If you say
如果你说
cmd /c "c:\Program Files\foo"
you'll run foo.exe
(with no arguments) whereas if you say
你会跑foo.exe
(没有参数),而如果你说
cmd /s /c "c:\Program Files\foo"
you'll run Program.exe
with Files\foo
as the argument.
你会碰到Program.exe
与Files\foo
作为参数。
(Oddly enough, in the first example, if foo.exe
didn't exist, Program.exe
would run instead.)
(奇怪的是,在第一个示例中,如果foo.exe
不存在,Program.exe
则会运行。)
Addendum:if you were to type
附录:如果你要输入
c:\Program Files\foo
at the command prompt, you would run Program.exe
(as happens with cmd /s /c) rather than foo.exe
(as happens with just cmd /c). So one reason for using /s would be if you want to make sure a command is parsed in exactly the same way as if it were being typed at the command prompt. This is probably more likely to be desirable in the scenario in the question Michael Burr linked to, where cmd.exe is being launched by CreateProcess rather than from a batch file or the command line itself..
在命令提示符下,您将运行Program.exe
(就像 cmd /s /c 那样)而不是foo.exe
(就像 cmd /c 那样)。因此,使用 /s 的一个原因是,如果您想确保以与在命令提示符下键入的方式完全相同的方式解析命令。在 Michael Burr 链接的问题中,这可能更受欢迎,其中 cmd.exe 由 CreateProcess 启动,而不是从批处理文件或命令行本身启动。
That is, if you say
也就是说,如果你说
CreateProcess("cmd.exe", "cmd /s /c \"" MY_COMMAND "\"", ...)
then the string MY_COMMAND
will be parsed exactly as if it were typed at the command prompt. If you're taking command-line input from the user, or if you're a library processing a command line provided by an application, that's probably a good idea. For example, the C runtime library system() function might be implemented in this way.
那么字符串MY_COMMAND
将被完全解析,就好像它是在命令提示符下键入的一样。如果您从用户那里获取命令行输入,或者如果您是一个处理应用程序提供的命令行的库,这可能是一个好主意。例如,C 运行时库 system() 函数可能以这种方式实现。