James Ko
James Ko

Reputation: 34499

Why isn't for /f working in this batch script?

I'm trying to capture the output of a command in a batch script with for /f. Here is my code:

set RUNPS="powershell -NoProfile -ExecutionPolicy Bypass -Command"
set OLDPATHPS="[Environment]::GetEnvironmentVariable('PATH', 'User')"
for /f %%i in ('%RUNPS% %OLDPATHPS%') do ^
    set OLDPATH=%%i

When I run the script from the console, here is the output:

C:\Users\James\Downloads>testscript
' ' is not recognized as an internal or external command,
operable program or batch file.
' ' is not recognized as an internal or external command,
operable program or batch file.
' ' is not recognized as an internal or external command,
operable program or batch file.
...

On the other hand, when I run the command normally I get

C:\Users\James\Downloads>powershell -NoProfile -ExecutionPolicy Bypass -Command "[Environment]::GetEnvironmentVariable('PATH', 'User')"
C:\Users\James\.dnx\runtimes\dnx-clr-win-x86.1.0.0-beta6\bin;C:\Users\James\.dnx\bin;...

Why does this happen with for /f and what can I do to fix it?


EDIT: Thought it may have been an issue with the single quotes being unescaped. Tried using usebackq:

for /f usebackq %%i in (`%RUNPS% %OLDPATHPS%`) do ^
    set OLDPATH=%%i

But it looks like I'm getting the same output.

Upvotes: 0

Views: 100

Answers (2)

Magoo
Magoo

Reputation: 79983

Try this:

@ECHO OFF
SETLOCAL
set "RUNPS=powershell -NoProfile -ExecutionPolicy Bypass -Command"
set "OLDPATHPS=[Environment]::GetEnvironmentVariable('PATH', 'User')"
for /f "delims=" %%i in ('%RUNPS% "%OLDPATHPS%"') DO (
    set OLDPATH=%%i
)
SET o

GOTO :EOF

The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned. set /a can safely be used "quoteless".

The required syntax for the command is

powershell -NoProfile -ExecutionPolicy Bypass -Command "[Environment]::GetEnvironmentVariable('PATH', 'User')"

not

"powershell -NoProfile -ExecutionPolicy Bypass -Command" "[Environment]::GetEnvironmentVariable('PATH', 'User')"

The ' ' is not recognized ... message appears to be the consequence of attempting to use the caret. It appears to be invalid as you've used it - I've never seen that ateempted before.

Note that you need the "delims=" to ensure that a user-path-containing-spaces is not tokenised.

Upvotes: 1

Dennis van Gils
Dennis van Gils

Reputation: 3452

Why would you escape the linebreak after do? You should use:

set RUNPS="powershell -NoProfile -ExecutionPolicy Bypass -Command"
set OLDPATHPS="[Environment]::GetEnvironmentVariable('PATH', 'User')"
for /f %%i in ('%RUNPS% %OLDPATHPS%') do (
set OLDPATH=%%i
)

Note that if you want to use variables like OLDPATH inside a for loop (after the do) you have to use setlocal EnableDelayedExpansion at the top of your script, and use ! instead of % for variables inside the loop

EDIT: your powershell currently has this exception:

-Command : The term '-Command' is not recognized as the name of a cmdlet, function, script file, or operable program.

Check the spelling of the name, or if a
path was included, verify that the path is correct and try again.

At line:1 char:1

  • -Command [Environment]::GetEnvironmentVariable('PATH', 'User')

  • ~~~~~~~~

    • CategoryInfo : ObjectNotFound: (-Command:String) [], CommandNot
      FoundException
    • FullyQualifiedErrorId : CommandNotFoundException

Upvotes: 1

Related Questions