[SOLVED] Error when quotes used in FOR /F statement

Discussion in 'Scripting' started by A-bit_Tinkerer, Mar 8, 2016.

  1. A-bit_Tinkerer

    A-bit_Tinkerer MDL Junior Member

    Mar 24, 2014
    61
    45
    0
    #1 A-bit_Tinkerer, Mar 8, 2016
    Last edited by a moderator: Apr 20, 2017
    I am looking to use an environment variable for the command in a FOR /F ('command') statement.

    Using an Administrator command prompt window:


    Quotes around DISM command in FOR /F statement cause an error:
    Code:
    C:\>for /F %i in ('"%windir%\system32\dism.exe" /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd" ^| find /C "Index"') do set images=%i
    The filename, directory name, or volume label syntax is incorrect.
    

    No error after quotes around DISM command removed:
    Code:
    C:\>for /F %i in ('%windir%\system32\dism.exe /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd" ^| find /C "Index"') do set images=%i
    
    
    C:\>set images=2
    
    In a command script, I want to replace %windir%\system32\dism.exe with %DISM_exe%, which could have a path with spaces, so I would need to use quotes like "%DISM_exe%".

    The FOR /F statement is being used to count the number of indexes in an install.esd file a save the the result in the images environment variable.

    Does any on know a solution that allows quotes to be used around the FOR /F command?
     
  2. KNARZ

    KNARZ MDL Addicted

    Oct 9, 2012
    880
    457
    30
    try: for /F "usebackq" %i in ('"%windir%\system32\dism.exe" /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd" ^| find /C "Index"') do set images=%i
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. A-bit_Tinkerer

    A-bit_Tinkerer MDL Junior Member

    Mar 24, 2014
    61
    45
    0
    #3 A-bit_Tinkerer, Mar 9, 2016
    Last edited by a moderator: Apr 20, 2017
    (OP)
    The suggested line did not actually use back quotes in the FOR /F (`command`). The result is:
    Code:
    C:\>for /F "usebackq" %i in ('"%windir%\system32\dism.exe" /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd" ^| find /C "Index"') do set images=%i
    
    C:\>set images="C:\Windows\system32\dism.exe"
    
    However, I should have mentioned that I had already tried the "usebackq" option and it does not work either.
    Code:
    C:>for /F "usebackq" %i in (`"%windir%\system32\dism.exe" /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd" ^| find /C "Index"`) do set images=%i
    The filename, directory name, or volume label syntax is incorrect.
    
    Thanks for taking the time to respond and offer a suggestion.
     
  4. Flipp3r

    Flipp3r MDL Expert

    Feb 11, 2009
    1,555
    664
    60
    #4 Flipp3r, Mar 10, 2016
    Last edited by a moderator: Apr 20, 2017
    What if you add the path to dism 1st like so:
    Code:
    @echo off
    setlocal
    set path=C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM;%path%
    
    for /F %%i in ('dism.exe /English /Get-WimInfo /WimFile:"w10_10586_64.esd" ^| find /C "Index"') do set images=%%i
    echo Images: %images%
    endlocal
     
  5. A-bit_Tinkerer

    A-bit_Tinkerer MDL Junior Member

    Mar 24, 2014
    61
    45
    0
    Adding the dism.exe folder to the beginning of the PATH variable does work. Quotes are not needed in the FOR /F ('command').

    Thank you Flipp3r for your solution.
     
  6. KNARZ

    KNARZ MDL Addicted

    Oct 9, 2012
    880
    457
    30
    I don't see any mistake in your original lines, I'm curious why it's not working with full path.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. wk-952

    wk-952 MDL Member

    Sep 2, 2012
    115
    285
    10
    #7 wk-952, Mar 11, 2016
    Last edited by a moderator: Apr 20, 2017
    To answer this very shortly, it's because the /F form of the for loop invokes a 2nd parsing session
    on the for loop input that works in a different way other than the normal command-line / batch parser.
    This parsing phase removes surrounding double-quote characters.

    I would like to try to explain this weird behavior in details,
    first let's study the behavior of the CMD when we type something that isn't a valid command.

    # Case 1)
    Open CMD and type something like this: C:\
    you'll get this error: (notice the syntax)
    Code:
    'C:\' is not recognized as an internal or external command,
    operable program or batch file.
    
    # Case 2)
    now type: "C:\"
    Code:
    '"C:\"' is not recognized as an internal or external command,
    operable program or batch file.
    
    So generally it is: <Single quote><the command you typed><Single quote> is not recognized...

    Let's go ahead and try this simple for loop, which should execute the command: C:\ (Case 1)
    Code:
    for /f %A in ('C:\') do echo:
    
    output:
    Code:
    'C:\' is not recognized as an internal or external command,
    operable program or batch file.
    
    same as Case 1, and that was expected.

    Now to the funky part!, let's mimic Case 2 but using a for loop:
    Code:
    for /f %A in ('"C:\"') do echo:
    
    output:
    Code:
    'C:\' is not recognized as an internal or external command,
    operable program or batch file.
    
    wait a second, where did the quotes go ?!
    and the simple plain answer to that is that they're removed!

    Let me show you some more weird/funky results, open CMD and try those:
    1)
    Code:
    for /f %A in ('"C:\"__"D:\"') do echo:
    
    output:
    Code:
    'C:\"__"D:\' is not recognized as an internal or external command,
    operable program or batch file.
    
    2)
    Code:
    for /f %A in ('""C:\""') do echo:
    
    output:
    Code:
    '"C:\"' is not recognized as an internal or external command,
    operable program or batch file.
    
    3) Notice that the 1st character is not a double-quote
    Code:
    for /f %A in ('_"C:\"__"D:\"') do echo:
    
    output:
    Code:
    '_"C:\"__"D:\"' is not recognized as an internal or external command,
    operable program or batch file.
    
    4)
    Code:
    for /f %A in ('""c:\""asd') do echo:
    
    output:
    Code:
    '"c:\"asd' is not recognized as an internal or external command,
    operable program or batch file.
    
    As a general rule: in the /F form of the for loop, if the first character is a double-quote,
    then this character along with the last double-quote (even if it's not the last char in the command-line)
    are both removed.

    So now you should know the root-cause of the your problem,
    and to solve it simply add an extra pair of surrounding quotes:
    Code:
    for /F %i in ('""%windir%\system32\dism.exe" /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd" ^| find /C "Index""') do set images=%i
    
    so that this extra useless pair gets removed instead of the original useful one.

    But, we're not finished yet!
    we've now broken the command-line / batch parser,
    watch how the above line will be interpreted: (red colors = literal string = not a command)
    Code:
    for /F %i in ('""%windir%\system32\dism.exe" /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd" ^| find /C "Index""') do set images=%i
    
    that looks completely wrong as opposed to what we want, isn't it ?
    and the solution is very simple, what caused this mess is the extra quotes pair, so let's make it non-effective.


    The final solution:
    Code:
    for /F %i in ('^""%windir%\system32\dism.exe" /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd" ^| find /C "Index"^"') do set images=%i
    

    EDIT: here's also a sample from the DISM log: (see how the command-line is correct)
    Code:
    2016-03-11 21:05:06, Info                  DISM   DISM.EXE: <----- Starting Dism.exe session ----->
    2016-03-11 21:05:06, Info                  DISM   DISM.EXE: 
    2016-03-11 21:05:06, Info                  DISM   DISM.EXE: Host machine information: OS Version=6.3.9600, Running architecture=amd64, Number of processors=4
    2016-03-11 21:05:06, Info                  DISM   DISM.EXE: Dism.exe version: 6.3.9600.17031
    2016-03-11 21:05:06, Info                  DISM   DISM.EXE: Executing command line: "C:\Windows\system32\dism.exe"  /English /Get-WimInfo /WimFile:"E:\x64\sources\install.esd"