cmd.exe chars needing quotes, and escaping redirection handles
Posted: 08 Jan 2020 16:03
Below are some newly discovered cmd.exe facts (at least for me) that likely no one cares about
1) Special characters listed in cmd help
The following statement at the end of the cmd help (HELP CMD or CMD /?) used to really irk me.
But then I read more carefully, and realized that the statement is related to file/directory completion via Ctrl-F and Ctrl-D
But of course Microsoft still is not quite correct - they forgot to list % as one of the special characters that requires quoting.
2) Escaping redirection file handles
It is fairly common knowledge within this community what will happen with the following:
A naive user might expect the statement "We will meet at 2" to be written to the file "output.txt". But the savvy user knows that "2" will be interpreted as the stderr file handle, so "We will meet at " will be sent to stdout (normally the console), and "output.txt" will be empty because there was no error output.
It is also fairly common knowledge that the solution is simple, move the redirection to the front (or anywhere where there is no chance of ambiguity)
Not sure how I got there, but I was reading a Raymond Chen blog Beware of digits before the redirection operator, and I learned that another option is to simply escape the "2"
It makes sense, but I had never thought to try it. I added one word to the Phase 2 redirection section of the Parsing Rules on StackOverflow to explicitly account for the behavior.
3) It is impossible to redirect to a file with a name beginning with &
Hopefully we all know what happens with the following:
The & introduces an already defined file handle on the right side of redirection, so the statement "Hello world " will be written to stderr (typically the console). After the revelation in point 2) above, I became interested in how to escape the & so that the output is written to a file named "&2" instead. I found it is impossible
None of the following work - they all write the output to stderr instead of a file.
Given that the first two attempts failed, I'm not surprised the last one failed as well, considering that the redirection occurs in Phase 5.5, after the delayed expansion in Phase 5.
It doesn't even work if there is no digit after the &
-- OUTPUT --
I suppose it might be possible to redirect to a file name beginning with & via a link, as in MKLINK "linkFile.txt" "&2". But I can't test on the machine I am currently working at because I don't have the required privilege.
I know jeb makes it a habit of disproving absolute claims like this, but I am pretty confident it is not possible to redirect to a file name beginning with & using standard cmd.exe commands (disregarding the possible MKLINK solution). Challenge on
Another interesting find - all text after &2 is simply ignored up until the first unquoted token delimiter.
--OUTPUT to stderr--
1) Special characters listed in cmd help
The following statement at the end of the cmd help (HELP CMD or CMD /?) used to really irk me.
I used to think "That is simply wrong! Characters like [ ] { and } are not special. How can Microsoft be so wrong?"cmd /? wrote: The special characters that require quotes are:
<space>
&()[]{}^=;!'+,`~
But then I read more carefully, and realized that the statement is related to file/directory completion via Ctrl-F and Ctrl-D
If file or directory completion is used, then any file/directory name that includes any of the special characters will be quoted.cmd /? wrote: If completion is enabled with the /F:ON switch, the two control
characters used are Ctrl-D for directory name completion and Ctrl-F for
file name completion. To disable a particular completion character in
the registry, use the value for space (0x20) as it is not a valid
control character.
Completion is invoked when you type either of the two control
characters. The completion function takes the path string to the left
of the cursor appends a wild card character to it if none is already
present and builds up a list of paths that match. It then displays the
first matching path. If no paths match, it just beeps and leaves the
display alone. Thereafter, repeated pressing of the same control
character will cycle through the list of matching paths. Pressing the
Shift key with the control character will move through the list
backwards. If you edit the line in any way and press the control
character again, the saved list of matching paths is discarded and a new
one generated. The same occurs if you switch between file and directory
name completion. The only difference between the two control characters
is the file completion character matches both file and directory names,
while the directory completion character only matches directory names.
If file completion is used on any of the built in directory commands
(CD, MD or RD) then directory completion is assumed.
The completion code deals correctly with file names that contain spaces
or other special characters by placing quotes around the matching path.
Also, if you back up, then invoke completion from within a line, the
text to the right of the cursor at the point completion was invoked is
discarded.
The special characters that require quotes are:
<space>
&()[]{}^=;!'+,`~
But of course Microsoft still is not quite correct - they forgot to list % as one of the special characters that requires quoting.
2) Escaping redirection file handles
It is fairly common knowledge within this community what will happen with the following:
Code: Select all
echo We will meet at 2>output.txt
It is also fairly common knowledge that the solution is simple, move the redirection to the front (or anywhere where there is no chance of ambiguity)
Code: Select all
>output.txt echo We will meet at 2
Code: Select all
echo We will meet at ^2>output.txt
3) It is impossible to redirect to a file with a name beginning with &
Hopefully we all know what happens with the following:
Code: Select all
echo Hello world >&2
None of the following work - they all write the output to stderr instead of a file.
Code: Select all
echo Hello world >^&2
echo Hello world >"&2"
set "file=&2"
setlocal enableDelayedExpansion
echo Hello world >"!file!"
It doesn't even work if there is no digit after the &
Code: Select all
echo Hello world >"&test.txt"
Code: Select all
The handle could not be duplicated
during redirection of handle 1.
I know jeb makes it a habit of disproving absolute claims like this, but I am pretty confident it is not possible to redirect to a file name beginning with & using standard cmd.exe commands (disregarding the possible MKLINK solution). Challenge on
Another interesting find - all text after &2 is simply ignored up until the first unquoted token delimiter.
Code: Select all
echo Hello world >"&2 this is ignored"and_so_is_this but_this_is_not_ignored
Code: Select all
Hello world but_this_is_not_ignored