What is `cmd / s`?

The Windows command line ( cmd.exe ) has the optional parameter /s , which changes the behavior of /c (it will launch a specific command and then exit) or /k (run a specific command and then display a shell prompt). This /s option obviously has something to do with some sort of secret quote management.

The docs are confusing, but as far as I can tell, when you do cmd /c something and something contains quotes, then by default cmd sometimes separates these quotes, and /s tells it to leave them alone.

I don’t understand when deleting a quote will break something, because only the time /s will be needed ("suppress default behavior for quotation"). It removes only quotation marks under a certain secret set of conditions, and one such condition is that the first character after /c must be a quotation mark. Therefore, it does not remove quotation marks around arguments; it either removes the quotes along the path to the EXE you are working on, or along the entire command line (or perhaps around the first half of the command line, which would be strange).

  • If the path to the EXE is specified, for example. cmd /c "c:\tools\foo.exe" arg1 arg2 , then the quotes are not needed, and if cmd wants to delete them, then a fine. (He will not delete them if the path has a space in the name - this is another secret rule.) I can not imagine any reason to suppress the removal of quotes, so /s seems unnecessary.
  • If the entire command line is quoted, for example. cmd /c "foo.exe arg1 arg2" , it seems that removing quotes would be necessary, since the system did not have an EXE named foo.exe arg1 arg2 ; therefore, it seems that abandoning the quote with /s will really upset the situation. (In fact, however, this does not break things: cmd /s /c "foo.exe arg1 arg2" works fine.)

Is there any subtlety in /s that eludes me? When will it ever be needed? When will it even matter?

+25
windows command-prompt
Mar 26 '12 at 5:20
source share
2 answers

Cmd / S is very useful, as it saves you from worrying about quoting quotes. Recall that the /C argument means "execute this command as if I typed it at the prompt and then exit."

So, if you have a complex command that you want to transfer to CMD.exe, you either need to remember the rules for quoting CMD arguments and properly avoid all quotes, or use /S , which runs the special non-parsing rule "Remove the first and last " and treat all other characters as a command to execute unchanged."

You would use it where you want to use the capabilities of the CMD shell, and not directly access another program. For example, expanding an environment variable, exiting or redirecting input, or using the built-in CMD.exe modules.

Example:

Use the built-in shell: this is done if you typed DEL /Q/S "%TMP%\TestFile" at the command line:

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

This does SomeCommand.exe redirect the standard output to the temp file and the standard error to the same place:

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

So, what gives /S extra? This basically eliminates the need to worry about quoting quotes. It also helps where you are not sure, for example, that the environment variable contains quotation marks. Just say /S and add an extra quote at the beginning and end.

Vaguely Linked: $ * to Bourne Shell.

Some background

Recall that the argument list main () is C-ism and Unix-ism. A Unix / Linux shell (for example, Bourne Shell, etc.) Interprets the command line, excludes arguments, extends wildcards, such as * , to file lists and passes the argument list to the program being called.

So if you say:

 $ vi *.txt 

The vi command, for example, sees the following arguments:

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

This is because unix / linux works internally based on an "argument list".

Windows, which ultimately comes from CP / M and VAX, does not use this system internally. On the operating system, the command line is just one line of characters. The responsibility of the called program is to interpret the command line, expand file globes ( * etc.) and process fuzzy quoted arguments.

So, the arguments expected by C must be cracked by the C runtime library. The operating system provides only one line with in arguments, and if your language is not C (or even if it is), it cannot be interpreted as arguments separated by spaces specified in accordance with the rules of the shell, but as something completely different.

+14
Mar 26 2018-12-12T00:
source share

Here is an example of how this might change.

Suppose you have two executable files: c:\Program.exe and c:\Program Files\foo.exe .

If you say

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

you run foo.exe (with no arguments), whereas if you say

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

as an argument, you execute Program.exe with Files\foo .

(Oddly enough, in the first example, if foo.exe did not exist, Program.exe run instead.)

Addendum: if you typed

  c:\Program Files\foo 

at the command line, you will run Program.exe (as it happens with cmd / s / c), and not foo.exe (as it happens with cmd / c only). Therefore, one of the reasons for using / s would be if you want to make sure that the command is parsed exactly as if it were entered on the command line. This is likely to be desirable in a script in a question related to Michael Burr, where cmd.exe is run by CreateProcess, and not from the batch file or the command line itself.

That is, if you say

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

then the MY_COMMAND string will be parsed exactly as if it were entered on the command line. If you take command line input from the user or if you are a library that processes the command line provided by the application, this is probably a good idea. For example, the C runtime library system () function can be implemented this way.

+10
Mar 26 2018-12-12T00:
source share



All Articles