carveone
carveone

Reputation: 909

Quoting a long filenamed command in a for loop in a batch file

Linked:

Best free resource for learning advanced batch-file usage?

Dealing with quotes in Windows batch scripts

This appears to be one of those maddening quoting issues. In this example program:

@echo off
set wmicpath=%windir%\System32\wbem\wmic.exe

for /f "usebackq" %%a in (`%wmicpath% COMPUTERSYSTEM GET SystemType ^| findstr /I "x64"`) do (
    echo %%a
)

The program runs just fine. Unless you try to quote the wmicpath. Imagine if you will that it contains a long path name. Then you should quote it. But I cannot quite get it to work. This fails:

for /f "usebackq" %%a in (`"%wmicpath%" COMPUTERSYSTEM GET SystemType ^| findstr /I "x64"`) do (

but this works!:

for /f "usebackq" %%a in (`"%wmicpath%" COMPUTERSYSTEM GET SystemType ^| findstr /I x64`) do (

as does this:

for /f "usebackq" %%a in (`"%wmicpath%" COMPUTERSYSTEM GET SystemType`) do (

There's something really odd about matching quotes in a for command. You can quote a command as long as you don't start quoting elsewhere...

Is it possible? I tried escaping at various points but I'm not sure about the escaping rules when quotes are involved...

Edit: I think this link might be the issue (ie: it's a bug): Pipe in for loop breaks double quoted variables

Upvotes: 0

Views: 1116

Answers (3)

MC ND
MC ND

Reputation: 70923

@echo off
    setlocal enableextensions disabledelayedexpansion
    set "wmicpath=%windir%\System32\wbem\wmic.exe"

    for /f "usebackq delims=" %%a in (`
        ^""%wmicpath%" COMPUTERSYSTEM GET SystemType ^| findstr /I "x64"^"
    `) do (
        echo %%a
    )

If you look at the start and end of the inner command, you will see two additional ^" (a escaped double quote). Your problem is that the for command is spawning a separate instance of cmd to handle the inner command, and this separate instance is removing the initial and final double quotes.

Why escaped quotes? To avoid this additional quotes being paired with the double quotes in the command that could lead to some other parsing problems.

You can run cmd /? to obtain the help page (sorry, i have a spanish locale so i will not include the output here). You will see a section about the /C and /K usage explaining quote removal behaviour.

Upvotes: 4

Compo
Compo

Reputation: 38623

First of all I would change the command, WMIC allows you to use a query language LIKE operator which would in this case remove the need to pipe anything.

@Echo Off
Set "WMIC=%SystemRoot%\System32\Wbem\wmic.exe"
For /F "UseBackQ Skip=1" %%a In (
    `""%WMIC%" ComputerSystem Where "SystemType Like 'x64%%'" Get SystemType"`
) Do For %%b In (%%a) Do Echo=%%b
Timeout -1

Then I may even change the format of the command such that I don't use back quotes.

@Echo Off
Set "WMIC=%SystemRoot%\System32\Wbem\wmic.exe"
For /F "Skip=1" %%a In (
    '""%WMIC%" ComputerSystem Where (SystemType Like "x64%%") Get SystemType"'
) Do For %%b In (%%a) Do Echo=%%b
Timeout -1

Whilst this doesn't directly answer the question in the subject title, it does allow for your particular command to work correctly.

However neither are necessary to your particular command example, because you do not need the for loop to echo that output:

@Echo Off
Set "WMIC=%SystemRoot%\System32\Wbem\wmic.exe"
"%WMIC%" ComputerSystem Get SystemType|Find /I "x64"
Timeout -1

Change Find to FindStr if you feel the need.

Upvotes: 1

Magoo
Magoo

Reputation: 80033

>x64.txt ECHO x64

for /f "usebackq" %%a in (`"%wmicpath%" COMPUTERSYSTEM GET SystemType ^| findstr /I /g:x64.txt`) do (

might be a work-around, depending on your actual application and preferences.

Upvotes: 0

Related Questions