views:

228

answers:

2

I've got a Windows batch script issue that I'm bashing my head against (no pun intended). The problematic script looks like this:

if defined _OLD_VIRTUAL_PATH (
    set PATH=%_OLD_VIRTUAL_PATH%
)

When I run it and _OLD_VIRTUAL_PATH is set I get:

\Microsoft was unexpected at this time.

_OLD_VIRTUAL_PATH is a variable that was originally set from PATH and it contains spaces - I'm pretty sure that's the problem. But what's the solution? It runs successfully if I enclose it in quotes, but I don't think the entire value of the PATH variable is supposed to be in quotes.

A: 

Well - I never knew about the defined operation in cmd scripts until just now...

Your script seems to work fine for me - which line exactly is producing the error?

You can also try:

if not "%_OLD_VIRTUAL_PATH%" == "" (
    set PATH=%_OLD_VIRTUAL_PATH%
)

And believe me, if you're coming into Windows cmd scripting expecting it to be anything like what you have in bash, your head will be very much in pain, very soon. You might want to look into using some other scripting language (PowerShell, Python, PERL - anything) if cmd scripting isn't an absolute requirement. the biggest thing (maybe the only thing) that cmd scripting has going for it is that it's already installed on every Windows box.

Michael Burr
There is a "defined" operator in Command Extensions - that line works OK. It's the `set` line that fails.
Evgeny
the set command works fine for me, even with spaces in `_OLD_VIRTUAL_PATH`. What is `_OLD_VIRTUAL_PATH` set to exactly? Is your script formatted exactly like you have it in the question (cmd.exe can be very picky about syntax, and not always in an intuitive way).
Michael Burr
+3  A: 

Your problem here are not the spaces but rather a closing parenthesis. You are probably running a 64-bit system where the Program Files directory for 32-bit applications has parentheses in its name. In a parenthesized block in a batch file this is a sure way to end the block and the rest of the line causes a syntax error.

You have two ways of mitigating this:

Either put the complete set argument in quotes; this causes the closing paren to not be recognized as end of block:

if defined _OLD_VIRTUAL_PATH (
    set "PATH=%_OLD_VIRTUAL_PATH%"
)

Or, the simpler one, just don't use a block for a single-line statement:

if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%

Yes, the batch syntax is weird at times, but the error message telling you where the syntax error occurred should give you a hint what to look for.

Chris Schmich
Wow - I learned 2 things today... I was certain that this syntax would blow up, but sure enough, it works. However, I'm not sure why it would be needed for Evgeny - setting a PATH with spaces has never been a problem for me without using quotes. Maybe Evgeny's `_OLD_VIRTUAL_PATH` has some other special character (other than a space) that needs quoting?
Michael Burr
@Michael: It's not the spaces that are the problem. I rewrote the post (hope Chris doesn't mind; he can roll back if needed) and explained what's wrong and why.
Joey
Thanks Johannes, I had forgotten the reason, but that definitely makes sense.
Chris Schmich
@Johannes: good catch. I actually ran into this problem about a year ago in a script I use to call various compilers from within a text editor. The script broke when I used it on a Win64 machine because of the `')'` in various env variable values (and/or the variable name - like `ProgramFiles(x86)` - I can't remember if having the `')'` in the name itself was a problem or not). Anyway, the hacks I came up with to workaround the problem were nowhere near as nice(?) as the workaround in this answer. Thanks to Chris and to you for this workaround and explanation.
Michael Burr
Thanks, enclosing the entire thing in quotes works! You're right, I do have "C:\Program Files (x86\Microsoft ..." in the path and that must have been the problem. It is actually a multi-line block, I just simplified it to one line for this post.
Evgeny