Shoelaced
Shoelaced

Reputation: 881

Removing leading/trailing slashes in .BAT file ruins everything

I'm having a lot of trouble figuring out why my .bat file randomly closes... but I've narrowed it down to this:

IF %var:~-1%==\ SET var=%var:~0,-1%
IF %var:~0,1%==\ SET var=%var:~1%

Ideally what I'm eventually trying to accomplish is to remove any leading or trailing slashes or backslashes from %var%, which is set by user input.

The above lines work, but not when inside an IF statement when setlocal EnableDelayedExpansion is set AND when the variable is also set inside the IF statement.

For example, the following works if I remove the above lines, but crashes otherwise:

@echo off
setlocal EnableDelayedExpansion
set somevar=blah
if !somevar!==blah (
    set /p var="-> "
    IF %var:~-1%==\ SET var=%var:~0,-1%
    IF %var:~0,1%==\ SET var=%var:~1%
    echo !var!
)
pause

If I remove the IF condition, however, it does work:

@echo off
setlocal EnableDelayedExpansion
set /p var="-> "
IF %var:~-1%==\ SET var=%var:~0,-1%
IF %var:~0,1%==\ SET var=%var:~1%
echo !var!
pause

And if I keep the IF statement but move the set /p var="-> " outside of it, then it also works:

@echo off
setlocal EnableDelayedExpansion
set somevar=blah
set /p var="-> "
if !somevar!==blah (
    IF %var:~-1%==\ SET var=%var:~0,-1%
    IF %var:~0,1%==\ SET var=%var:~1%
    echo !var!
)
pause

I know that when Delayed Expansion is enabled that I have to use ! instead of % for variables, but I've tried every combination of that on those lines to no avail, and I don't understand how they work enough to troubleshoot further.

And if there's a more efficient way to accomplish what I've described, by all means please mention it. I'm somewhat new to batch-writing.

Upvotes: 0

Views: 375

Answers (1)

Magoo
Magoo

Reputation: 80203

As you've implied, the key to your problem is the use of delayed expansion.

When delayedexpansion has been invoked,

%var% refers to the value of var as it was when any code block (parenthesised sequence of instructions) was encountered (actually, var is simply replaced by its value at that time and then the instructions are executed)

!var! refers to the run-time value of var - that is, the value at the current time, having possibly been altered by the operation of the code block.

so, examining from your code

set /p var="-> "
IF %var:~-1%==\ SET var=%var:~0,-1%
IF %var:~0,1%==\ SET var=%var:~1%
echo !var!

This is executed as

set /p var="-> "
IF ==\ SET var=
IF ==\ SET var=
echo !var!

because the value of var at the start of the code is nothing, consequently it "crashes" because the if statement syntax is incorrect.

To fix the problem, use

set /p var="-> "
IF !var:~-1!==\ SET var=!var:~0,-1!
IF !var:~0,1!==\ SET var=!var:~1!
echo !var!

where each reference to var becomes the value as changed by the "set /p" or subsequent set operations.

However, set/p does not clear the variable if you simply press Enter. It leaves the variable unchanged (but its value happens to be nothing at the time)

Hence, a better approach is

set /p var="-> "
IF "!var:~-1!"=="\" SET "var=!var:~0,-1!"
IF "!var:~0,1!"=="\" SET "var=!var:~1!"
echo !var!

where the quotes around the if arguments ensure that the arguments are not empty and those around the set arguments ensure that the variable does not acquire any stray trailing spaces that may exist on the instruction line.

Upvotes: 1

Related Questions