0

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?

  • you only need [delayed expansion](https://stackoverflow.com/a/30284028/2152082) with variables that are changed within the same code block. `%path%` usually doesn't change (if you don't do it explicitely), so no delayed expansion is needed. – Stephan Jan 23 '18 at 12:50
  • @Stephan `%PATH%` and `!PATH!` are just examples of what I am referring to when I said percent variables and exclamation mark variables. I am not necessarily referring to the variable itself. – Christian Sirolli Jan 23 '18 at 13:18
  • put a comment, or give some hint for whoever will read your code to do a research – phuclv Jan 23 '18 at 13:31
  • please describe your concrete problem and give a [mcve] – Stephan Jan 23 '18 at 13:31
  • @Stephan I added an example – Christian Sirolli Jan 23 '18 at 14:19
  • you need to understand [how cmd parses the commands](https://stackoverflow.com/q/4094699/995714) to know why you need to use `!` instead of `%`. Seems you're insisting on solving some non-existent problem. If you want to work with blocks of code you must understand how delayed expansion works, and so do anyone who maintain the code later. Don't worry for them if they don't know why `!` is used. They need to learn, otherwise they won't be able to maintain the script – phuclv Jan 23 '18 at 14:52
  • You need to be specific with the issue with your added example. `USERPROFILE` is a predined variable which does not need delayed expansion to show. I do not see a direct issue with your example. – michael_heath Jan 23 '18 at 14:56
  • @michael_heath I have revised the question. I believe I know better of what is going on and what is not causing the issue. – Christian Sirolli Jan 24 '18 at 13:19

3 Answers3

1

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.

MichaelS
  • 5,941
  • 6
  • 31
  • 46
1
@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
michael_heath
  • 5,262
  • 2
  • 12
  • 22
1

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

Stephan
  • 53,940
  • 10
  • 58
  • 91