[英]SHIFT doesn’t affect %*
我正在尝试将一些可选参数添加到批处理文件中但由于SHIFT
命令不影响所有参数变量%*
而遇到问题。
如果我必须使用%*
有谁知道如何允许可选的批处理文件参数?
例如,一个简单的例子,仅使用和不使用换行符将屏幕上的参数打印出来,使用可选参数来确定:
@echo off
if (%1)==() goto usage
if (%1)==(/n) goto noeol
goto eol
:eol
echo %*
goto :eof
:noeol
shift
call showline %*
goto :eof
:usage
echo Prints text to the screen
echo > %0 [/n] TEXT
echo /n to NOT print a new-line at the end of the text
goto :eof
如您所知, shift
对%*
没有影响,但您可以构造%*等效项。
我们将调用以下line.bat
:
@echo off
set line=%1
:loop
shift
if not "%1"=="" (
set line=%line% %1
goto :loop
)
echo %%* = %*
echo line = %line%
如果键入以下命令(请注意3和4之间的双倍空格) :
line 1 2 3 4 bla dee dah
您将获得以下输出:
%* = 1 2 3 4 bla dee dah
line = 1 2 3 4 bla dee dah
请注意, %*
保留多个空格,而使用%n
表示法则不会。
使用这样的东西,您可以允许您的用户以任何顺序放置他们的参数。
:loop
:: Single variable parameters
if "%1"=="something" set something=true
:: Multi variable parameters
if "%~1"=="/source" shift & set source=%1
shift
if not "%~1"=="" goto :loop
请注意,在Multi-variable参数语句中,我包含一个shift
语句和一个用&符号分隔的set
语句。 &
告诉命令处理器,接下来要执行一个单独的命令。
编辑:
仅供参考:我在检查变量内容时建议使用双引号。 通常你可以使用任何字符,你甚至不需要使用两个字符,因为它们只是确保空变量不会导致错误。 例如,当%1
为空并且if not hello==%1 call :sub
命令处理器将看到这个, if not hello== call :sub
并比较hello
来call
然后尝试执行:sub
,并抛出一个错误。 在那个特定情况下, if not xhello==x%1 call :sub
就好if not "hello"=="%1" call :sub
,因为空%1
将导致命令处理器看看if not xhello==x call :sub
。
但是,如果变量包含任何特殊字符,则使用双引号以外的字符会导致问题。
使用括号作为变量分隔符(如(%1))可能会导致问题。 例如,(特殊)管道符号在括号内不能很好地使用,并且转义字符似乎消失了,既不作为普通字符,也不作为转义字符。
括号也是特殊字符,它们本身用于分组和/或分隔不同的代码行,并且可能并不总是按预期行事。
最后,双引号本身是专门设计用于包围其他特殊字符的特殊字符 ,允许它们充当普通字符。 这就是为什么你可能会看到变量没有引用,然后再次引用,就像这样。
set var="%~1" & REM This sort of thing is used to insure that a variable is quoted.
REM %~1 unquotes %1 if it is already quoted, and leaves it alone if
REM %1 is not quoted.
set "var=%~1" & REM This code assumes that `%1` contains special characters and
REM like before unquotes a quoted %1, but leaves the variable itself
REM unquoted. The double-quotes surrounding the variable and data
REM protects the command processor from any special characters that
REM exist in the data. Remember that anytime you reference `%var%`,
REM you will need to also surround the variable and data with
REM double-quotes.
if exist %1 if %1==%~1 echo Unquoted
快速检查引号if exist %1 if %1==%~1 echo Unquoted
。
我喜欢詹姆斯的解决方案,因为它不需要用户提供任何特殊的东西(这总是更好),但我只想到另一种方式; 将参数放在引号中并在运行时删除它们:
Print.bat:
@echo off
if (%1)==() goto usage
if (%1)==(/n) goto noeol
goto eol
:eol
:: Use %~1 to
echo %~1
goto :eof
:noeol
shift
call showline %~1
goto :eof
:usage
echo Prints text to the screen
echo > %0 [/n] TEXT
echo /n to NOT print a new-line at the end of the text
goto :eof
Results:
C:\>print.bat "foo bar baz"
foo bar baz
C:\>print.bat /n "foo bar baz"
foo bar baz
C:\>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.