Search code examples
windowsbatch-filecmdenvironment-variables

Batch File and Quoting Variables


I'm working with a batch file and I was wondering, why do some variables have double quotes around them and others don't, for example?

SET "keePass=%USERPROFILE%\KeePass\KeePass-2.31\KeePass.exe"

but this:

SET name="bob"

Why the double quotes in the first one, but not the second?


Solution

  • ...to provide the conclusion at the beginning:

    Supposing you have got the command extensions enabled (which is the default setting of the Windows command prompt cmd), the best practice is to use the following set syntax:

    set "VAR=value"
    

    (The command extensions can be enabled/disabled by cmd (type cmd /? in a command prompt window for help) or, within batch files only, by setlocal (type setlocal /? for details).)


    At first, let us take a look at the standard syntax mentioned in the help text, that appears when typing set /? (or help set) in a command prompt window:

    set VAR=value
    

    This assigns the string value to the variable VAR obviously.

    The good thing of this syntax is:

    • it also works when the command extensions are disabled;
    • the variable value is not surrounded by quotation marks (supposing value does not contain such on its own), so there is only one place to take care of them, namely during variable expansion (like %VAR% or "%VAR%", depending on the situation at hand; this is particularly useful when combining strings like constant_%VAR% or "constant_%VAR%", which will be expanded to constant_value or "constant_value", respectively, so you always have full control over the placement of the quotation marks; if the value contained the enclosing "", constant_%VAR% would expand to constant_"value", which might probably not be the string you want to have);

    But there might occur some problems:

    • any (invisible) trailing white-space becomes part of the string value, so if the command line is followed by a single SPACE character, VAR will carry the value valueSPACE;
    • when you concatenate this command with another command, like set VAR=value & echo Text, the SPACE before the & character becomes part of the value; you could of course write set VAR=value&echo Some text, but this was quite difficult to read;
    • if value contains special characters, like ^ & ( ) < > |, you might run into problems; for example, set VAR=1&2 will assign 1 to VAR, then an error will arise, because & separates two commands and 2 is not a valid one;

    The syntax of the second example in your question is quite similar:

    set VAR="value"
    

    This assigns the string "value" to VAR, so the quotation marks are included in the value.

    The advantages are:

    • it also works when the command extensions are disabled;
    • special characters (like ^ & etc.) in value do not cause any trouble because of the "";

    But still:

    • the quotation marks become part of the value, which may be disturbing in numerous situations;
    • unwanted trailing white-spaces (after the last ") still become part of the string value;
    • again when concatenating this command with another command using &, you have to omit spaces around the ampersand;

    Now, let us check out the syntax of the first example in your question:

    set "VAR=value"
    

    This assigns value to VAR. Since the quotation marks are placed around the entire assignment expression, they are removed before the assignment is actually accomplished.

    This has got several advantages:

    • the quotation marks do not become part of the variable value;
    • any (unintended) trailing white-spaces do not become part of the variable value;
    • you can concatenate it with another command using SPACE&SPACE without any unwanted spaces being appended to the value;
    • special characters (like ^ & etc.) in value are no problem;

    But there is one issue:

    • the command extensions need to be enabled for this syntax to work; otherwise, an error arises;

    Finally, you could also combine the above syntaxes, if you do want the quotation marks to become part of the variable value (although I do not recommend that):

    set "VAR="value""
    

    This assigns "value" to VAR.

    Advantages:

    • unwanted trailing white-spaces (after the last ") do not become part of the variable value;
    • you can concatenate it with another command using SPACE&SPACE without any unwanted trailing spaces in the value;

    Disadvantages:

    • the quotation marks become part of the value, which may be disturbing in numerous situations;
    • the command extensions need to be enabled for this syntax to work; otherwise, an error arises;
    • special characters (like ^ & etc.) in value may cause problems; this is because of the way the command parser works: as soon as the first " is encountered, any special characters are no longer recognised, they are treated as literal characters; after the next ", special character recognition becomes re-activated, and so on; regard that this is also true in case value itself contains any quotation marks on its own;

    Side Note:

    Never put spaces around the equal-to sign in a set command line, because they will become part of the variable name and/or value. For instance, the command lines

    set VAR = value
    

    and

    set "VAR = value"
    

    both assign the string value SPACEvalue to a variable named VARSPACE.