Skip to content

How cmd.exe extracts a command

johnstevenson edited this page Aug 4, 2016 · 1 revision

This section describes how cmd.exe reads its command-line to extract a command to be processed:

cmd.exe /c "command"

The /c option instructs it to carry out the specified command and then terminate. It uses the command-line it was created with, identifies the relevant part and then does some preliminary double-quote processing. The result will subsequently be parsed into one or more commands to executed. From the help:

If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:

1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:

        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          two quote characters
        - the string between the two quote characters is the name
          of an executable file.

2.  Otherwise, old behavior is to see if the first character is
    a quote character and if so, strip the leading character and
    remove the last quote character on the command line, preserving
    any text after the last quote character.

Examples

The following will be matched by the first rule and the intended command-line will not be modified:

call:     cmd.exe /c "my prog.exe" param1 > out.txt

result:   "my prog.exe" param1 > out.txt

If more than two double-quotes are used, the second rule will be applied. As a result the first and last quotes will be removed, which will break the command:

call:     cmd.exe /c "my prog.exe" "param 1" > out.txt

result:   my prog.exe" "param 1 > out.txt

The safest method is to always force the use of the second rule by enclosing the command in double-quotes:

call:     cmd.exe /c ""my prog.exe" "param 1" > out.txt"

result:   "my prog.exe" "param 1" > out.txt