Christian Sirolli
Christian Sirolli

Reputation: 307

How to use percent variables as variables from user inputted commands?

In batch scripting, is it possible to use percent variables (e.g. %PATH%) from user inputted commands? I am creating a batch script that uses a user's input to run certain commands, and I want users to be able to use variables in the commands, but it doesn't work. I can use exclamation mark variables when I use SETLOCAL EnableDelayedExpansion, but with it enabled or disabled, the percent variables won't work. For users who are unfamiliar with using exclamation mark variables (e.g. !PATH!), I want it to be possible for the percent variables to be used. Any ideas why it doesn't work?

As per the comments, an example was requested. Here is a very basic version of what I have:

ECHO OFF
TITLE Batch Prompt
CLS
ECHO Test this code using "ECHO <command here>"
CD %USERPROFILE%
:CMD
set /P "COMMAND=>"
%COMMAND%
GOTO CMD

You can test this by copying it to Notepad and saving it as a Batch file, and using ECHO to see how it treats variables. Don't try any other command, since in this very basic version it may not work.

As can be seen upon testing, any variable using percent symbols (e.g. %HOMEDRIVE%) is not being displayed. But enable delayed expansion, and use exclamation marks (e.g. !HOMEDRIVE!) and it's value is displayed.

So how can I get this to work with the percent variables? Any idea what is going on that is causing this issue?

Upvotes: 0

Views: 735

Answers (3)

michael_heath
michael_heath

Reputation: 5372

@echo off

set args="!literal!" "literal!"
call :label_1 %args%
call :label_2 %args%

setlocal enabledelayedexpansion
echo %args%
endlocal
echo %args%

goto :eof

:label_1
setlocal enabledelayedexpansion
echo %args%
goto :eof

:label_2
setlocal disabledelayedexpansion
echo %args%
goto :eof

As above example shows, if a user passes arguments such as "!literal!" "literal!", then the argument can be treated as a variable name with double exclaimations which could be undefined or a value of an already set variable value. Also with a single exclaimation, the exclaimation can be removed.

Thus you may need to disable delayed expansion in parts of your code and enable it where considered safe i.e. when not handling the users arguments.

Output of example:

"" "literal"
"!literal!" "literal!"
"" "literal"
"!literal!" "literal!"

The first and third lines show an issue with enableddelayedexpansion.


Response to updated question.

%COMMAND% has unexpanded i.e. %HOMEDRIVE% as a literal value from the user input. You can call a label with %COMMAND% as the argument. Inside the label, %COMMANDS% is set with the expanded argument. %COMMAND% after the call has now expanded %HOMEDRIVE%.

Example:

@echo off
set /p "COMMAND=>"
call :expand_args %COMMAND%
echo testing: %COMMAND%
%COMMAND%
goto :eof

:expand_args
set COMMAND=%*
goto :eof

Upvotes: 1

Stephan
Stephan

Reputation: 56180

Replace the line %COMMAND% with call %COMMAND%, which adds another layer of expansion

Upvotes: 1

MichaelS
MichaelS

Reputation: 6042

DelayedExpansion allows you to use exclamation mark variables but it doesn't influence the use of "regular" variables like %path%. So if DelayedExpansion is set you can use both otherwise only %var% is available.

Upvotes: 1

Related Questions