Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

windows cmd: problems with for /f with a quoted command with quoted parameters

for /f "delims=" %%a in ('"%systemRoot%\system32\find.exe" /?') do @echo %%a

Yes, the previous line works. Not much useful but works. But trying write a batch file to answer another question, i faced something like

 for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v "" ^< "c:\something.txt"') do @echo %%a
 for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v ""    "c:\something.txt"') do @echo %%a

Both of the previous lines return The filename, directory name, or volume label syntax is incorrect

 for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v "" ^< c:\something.txt'  ) do @echo %%a
 for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v ""    c:\something.txt'  ) do @echo %%a

Both of the previous lines return The system cannot find the file specified

I've been unable to make it work, neither scaping the quotes, doubling them, preceding with backslashes, changing to single quotes to backquotes and setting the corresponding option in for command, all the combinations that i tried failed.

If the command to run is quoted and it takes quoted arguments it fails.

And yes, i know the quotes surounding the find are not needed, and if removed, any of the previous four lines will work (ignoring the output, delims, tokens)

But in the case where the quotes surounding the command are really needed (and i know systems where 8dot3name behaviour is disabled), is there any way to make it work? what am i missing here?

like image 481
MC ND Avatar asked Mar 25 '14 13:03

MC ND


People also ask

How do I escape double quotes in CMD?

Double quotes enable escaping through the use of the backslash (\). For example, if the special character semicolon is a value that is double-quoted, it should be represented as backslash semicolon (\;) so that the Integration Engine knows that the actual value (;) should be used.

How do I escape special characters in CMD?

The Windows command-line interpreter uses a caret character ( ^ ) to escape reserved characters that have special meanings (in particular: & , | , ( , ) , < , > , ^ ).

What does %% A mean in CMD?

Use double percent signs ( %% ) to carry out the for command within a batch file. Variables are case sensitive, and they must be represented with an alphabetical value such as %a, %b, or %c. ( <set> ) Required. Specifies one or more files, directories, or text strings, or a range of values on which to run the command.

How do I use special characters in CMD?

In Windows, you can type any character you want by holding down the ALT key, typing a sequence of numbers, then releasing the ALT key.


1 Answers

Here are two solutions.

1) has surrounding double quotes and removed ^ escape character.
2) uses find as it is on the path.

for /f %%a in ('""%systemRoot%\system32\find.exe" /c /v "" < "c:\something.txt""') do @echo %%a

for /f %%a in (' find.exe /c /v "" ^< "c:\something.txt"') do @echo %%a

It's to do with launching an extra cmd process to run the command-line inside the for command.

Curiously, these three commands fail differently in an even simpler context.

for /f %%a in (' "c:\windows\system32\find.exe" /c /v ""  something.txt ') do @echo %%a

The system cannot find the path specified.

for /f %%a in (' "c:\windows\system32\findstr.exe" /n "."  something.txt ') do @echo %%a

The directory name is invalid.

for /f %%a in (' "c:\windows\notepad" "something.txt" ') do @echo %%a

'c:\windows\notepad" "something.txt' is not recognized as an internal or external command, operable program or batch file.

This last one gives a clue that the outer quotes are being stripped.

Windows 8.1 32 bit

I think the quote issue is described here in cmd /? when a child process is invoked:

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.
like image 83
foxidrive Avatar answered Sep 21 '22 02:09

foxidrive