Reputation: 207
I have a scenario:
FORFILES /P "C:\users\DominiqueGerry\Work Files\" /S /M *.doc /C "cmd /c echo @fsize"
gives me an error:
ERROR: Invalid argument/option - '@fsize'.
Type "FORFILES /?" for usage.
But when I remove the slash, it works:
FORFILES /P "C:\users\DominiqueGerry\Work Files" /S /M *.doc /C "cmd /c echo @fsize"
I do not understand why this does not work without the backslash, but does not with it. I cannot find any official documentation explaining this. and do not even see any of it mentioned when running help forfiles /?
I would appreciate any help on this.
The best part is. The error is not even related to the issue at hand.
Upvotes: 4
Views: 1733
Reputation:
To be honest, I do not think it is documented anywhere in the official help (at least not what I have seen), but what actually happens is that the trailing backslash is actually escaping the last double quote. In my mind, this is actually a bug.
The reason why the error is not related is simply because the forfiles
command detects an error in the format, due to the missing double quote, which the backslash escaped.
You will see that this does not happen when you do not have the double quotes, so let's assume you have no space in your path:
FORFILES /P C:\users\DominiqueGerry\WorkFiles\ /S /M *.doc /C "cmd /c echo @fsize"
Would not give you an error, simply because the baskslash does not have any valid character to escape, problem is, you do have a space in path, so you must use double quotes. So it is best to retain the double quotes and not add the trailing backslash:
FORFILES /P "C:\users\DominiqueGerry\Work Files" /S /M *.doc /C "cmd /c echo @fsize"
Or if you are adamant on using the backslash, simply escape it by doubling up.
FORFILES /P "C:\users\DominiqueGerry\Work Files\\" /S /M *.doc /C "cmd /c echo @fsize"
Edit, also as mentioned in comments by @aschipfl you can use .
:
FORFILES /P "C:\users\DominiqueGerry\Work Files\." /S /M *.doc /C "cmd /c echo @fsize"
Upvotes: 6
Reputation: 5372
C/C++ sources compiled into executables may follow Parsing C++ Command-Line Arguments
Microsoft C/C++ startup code uses the following rules when interpreting arguments given on the operating system command line:
Arguments are delimited by white space, which is either a space or a tab.
The caret character (^) is not recognized as an escape character or delimiter. The character is handled completely by the command-line parser in the operating system before being passed to the argv array in the program.
A string surrounded by double quotation marks ("string") is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
A double quotation mark preceded by a backslash (\") is interpreted as a literal double quotation mark character (").
Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
If an even number of backslashes is followed by a double quotation mark, one backslash is placed in the argv array for every pair of backslashes, and the double quotation mark is interpreted as a string delimiter.
If an odd number of backslashes is followed by a double quotation mark, one backslash is placed in the argv array for every pair of backslashes, and the double quotation mark is "escaped" by the remaining backslash, causing a literal double quotation mark (") to be placed in argv.
Quite common for C++ programs. The command interpreter started it's life before
the C++ argument handling mentioned was established. reg.exe
and other programs
compiled from C++ sources usually have this argument handling.
forfiles.exe
is not a builtin command to the command interpreter, so the
builtin help of cmd.exe
will not inform you of how external executables
may behave.
As you have found, you can escape a double quote with a backslash i.e. \"
.
This allows you to have double quotes in string within double quotes i.e.
"\"string\""
so that the quotes are retained by the program that the
argument has been passed to. To escape the escape, double up the backslash i.e. \\
.
The error you receive is 1 double quote of a pair being removed and the escaped double quote is retained, thus the remaining double quote causes a syntax error.
Upvotes: 0