我需要在运行时将ID和密码传递给批处理文件,而不是将它们硬编码到文件中.
这是命令行的样子:
test.cmd admin P@55w0rd > test-log.txt
Greg Hewgill.. 981
另一个有用的提示是用来%*
表示"全部".例如:
echo off set arg1=%1 set arg2=%2 shift shift fake-command /u %arg1% /p %arg2% %*
当你运行:
test-command admin password foo bar
上面的批处理文件将运行:
fake-command /u admin /p password admin password foo bar
我的语法可能略有错误,但这是一般的想法.
另一个有用的提示是用来%*
表示"全部".例如:
echo off set arg1=%1 set arg2=%2 shift shift fake-command /u %arg1% /p %arg2% %*
当你运行:
test-command admin password foo bar
上面的批处理文件将运行:
fake-command /u admin /p password admin password foo bar
我的语法可能略有错误,但这是一般的想法.
我是这样做的:
@fake-command /u %1 /p %2
这是命令的样子:
test.cmd admin P@55w0rd > test-log.txt
在%1
适用于第一个参数%2
(这里是棘手的部分)适用于第二.您最多可以以这种方式传递9个参数.
如果您想要智能地处理缺少的参数,您可以执行以下操作:
IF %1.==. GOTO No1 IF %2.==. GOTO No2 ... do stuff... GOTO End1 :No1 ECHO No param 1 GOTO End1 :No2 ECHO No param 2 GOTO End1 :End1
使用%1,%2,...%9或%*访问批处理参数可以很简单,
但仅限于内容很简单.
对于复杂的内容没有简单的方法"&"^&
,因为在不产生错误的情况下无法访问%1.
set var=%1 set "var=%1" set var=%~1 set "var=%~1"
线条扩展到
set var="&"& set "var="&"&" set var="&"& set "var="&"&"
并且每一行都失败了,因为其中一条线&
在引号之外.
它可以通过从临时文件中读取参数的标记版本来解决.
@echo off SETLOCAL DisableDelayedExpansion SETLOCAL for %%a in (1) do ( set "prompt=" echo on for %%b in (1) do rem * #%1# @echo off ) > param.txt ENDLOCAL for /F "delims=" %%L in (param.txt) do ( set "param1=%%L" ) SETLOCAL EnableDelayedExpansion set "param1=!param1:*#=!" set "param1=!param1:~0,-2!" echo %%1 is '!param1!'
诀窍是echo on
在rem
声明后启用和扩展%1 (也适用于%2 .. %*
).
因此,即使"&"&
可以回应也不会产生错误.
但是为了能够重定向输出echo on
,你需要两个for循环.
额外的字符* #
用于保护内容,例如/?
(显示帮助REM
).
或者在行尾的插入符^可以作为多行字符,即使在a之后rem
.
然后从文件中读取rem参数输出,但要小心.
FOR/F应该与延迟扩展一起使用,否则内容为"!" 会被摧毁.
删除多余的字符后param1
,你就明白了.
并以param1
安全的方式使用,启用延迟扩展.
是的,只是不要忘记使用变量,如%%1
使用if
和for
帮派.
如果您忘记了double %
,那么您将替换(可能为null)命令行参数,您将收到一些非常令人困惑的错误消息.
没有必要使它复杂化.它只是命令%1%2参数,例如,
@echo off xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z echo copied %1 to %2 pause
"暂停"显示批处理文件已完成的操作,并等待您按任意键.将其保存为Windows文件夹中的xx.bat.
要使用它,请键入,例如:
xx c:\f\30\*.* f:\sites\30
这个批处理文件负责所有必要的参数,比如只复制文件,更新等等.我在Windows之前使用过它.如果您希望在复制文件时查看文件的名称,请省略Q
参数.
一位朋友最近问我这个问题,所以我想我会发布如何在批处理文件中处理命令行参数.
正如您所看到的,这种技术有一些开销,但它使我的批处理文件非常易于理解和快速实现.以及支持以下结构:
>template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...]
它的JIST是具有:init
,:parse
和:main
功能.
用法示例
>template.bat /? test v1.23 This is a sample batch file template, providing command-line arguments and flags. USAGE: test.bat [flags] "required argument" "optional argument" /?, --help shows this help /v, --version shows the version /e, --verbose shows detailed output -f, --flag value specifies a named parameter value >template.bat <- throws missing argument error (same as /?, plus..) **** **** **** MISSING "REQUIRED ARGUMENT" **** **** **** >template.bat -v 1.23 >template.bat --version test v1.23 This is a sample batch file template, providing command-line arguments and flags. >template.bat -e arg1 **** DEBUG IS ON UnNamedArgument: "arg1" UnNamedOptionalArg: not provided NamedFlag: not provided >template.bat --flag "my flag" arg1 arg2 UnNamedArgument: "arg1" UnNamedOptionalArg: "arg2" NamedFlag: "my flag" >template.bat --verbose "argument #1" --flag "my flag" second **** DEBUG IS ON UnNamedArgument: "argument #1" UnNamedOptionalArg: "second" NamedFlag: "my flag"
template.bat
@::!/dos/rocks @echo off goto :init :header echo %__NAME% v%__VERSION% echo This is a sample batch file template, echo providing command-line arguments and flags. echo. goto :eof :usage echo USAGE: echo %__BAT_NAME% [flags] "required argument" "optional argument" echo. echo. /?, --help shows this help echo. /v, --version shows the version echo. /e, --verbose shows detailed output echo. -f, --flag value specifies a named parameter value goto :eof :version if "%~1"=="full" call :header & goto :eof echo %__VERSION% goto :eof :missing_argument call :header call :usage echo. echo **** **** echo **** MISSING "REQUIRED ARGUMENT" **** echo **** **** echo. goto :eof :init set "__NAME=%~n0" set "__VERSION=1.23" set "__YEAR=2017" set "__BAT_FILE=%~0" set "__BAT_PATH=%~dp0" set "__BAT_NAME=%~nx0" set "OptHelp=" set "OptVersion=" set "OptVerbose=" set "UnNamedArgument=" set "UnNamedOptionalArg=" set "NamedFlag=" :parse if "%~1"=="" goto :validate if /i "%~1"=="/?" call :header & call :usage "%~2" & goto :end if /i "%~1"=="-?" call :header & call :usage "%~2" & goto :end if /i "%~1"=="--help" call :header & call :usage "%~2" & goto :end if /i "%~1"=="/v" call :version & goto :end if /i "%~1"=="-v" call :version & goto :end if /i "%~1"=="--version" call :version full & goto :end if /i "%~1"=="/e" set "OptVerbose=yes" & shift & goto :parse if /i "%~1"=="-e" set "OptVerbose=yes" & shift & goto :parse if /i "%~1"=="--verbose" set "OptVerbose=yes" & shift & goto :parse if /i "%~1"=="--flag" set "NamedFlag=%~2" & shift & shift & goto :parse if not defined UnNamedArgument set "UnNamedArgument=%~1" & shift & goto :parse if not defined UnNamedOptionalArg set "UnNamedOptionalArg=%~1" & shift & goto :parse shift goto :parse :validate if not defined UnNamedArgument call :missing_argument & goto :end :main if defined OptVerbose ( echo **** DEBUG IS ON ) echo UnNamedArgument: "%UnNamedArgument%" if defined UnNamedOptionalArg echo UnNamedOptionalArg: "%UnNamedOptionalArg%" if not defined UnNamedOptionalArg echo UnNamedOptionalArg: not provided if defined NamedFlag echo NamedFlag: "%NamedFlag%" if not defined NamedFlag echo NamedFlag: not provided :end call :cleanup exit /B :cleanup REM The cleanup function is only really necessary if you REM are _not_ using SETLOCAL. set "__NAME=" set "__VERSION=" set "__YEAR=" set "__BAT_FILE=" set "__BAT_PATH=" set "__BAT_NAME=" set "OptHelp=" set "OptVersion=" set "OptVerbose=" set "UnNamedArgument=" set "UnNamedArgument2=" set "NamedFlag=" goto :eof
@ECHO OFF :Loop IF "%1"=="" GOTO Continue SHIFT GOTO Loop :Continue
注意:"%1"==""
如果%1
用引号括起来,IF 会引起问题.
在这种情况下,请使用IF [%1]==[]
或在NT 4(SP6)及以后的版本中使用IF "%~1"==""
.
让我们保持这个简单.
这是.cmd文件.
@echo off rem this file is named echo_3params.cmd echo %1 echo %2 echo %3 set v1=%1 set v2=%2 set v3=%3 echo v1 equals %v1% echo v2 equals %v2% echo v3 equals %v3%
这是来自命令行的3个调用.
C:\Users\joeco>echo_3params 1abc 2 def 3 ghi 1abc 2 def v1 equals 1abc v2 equals 2 v3 equals def C:\Users\joeco>echo_3params 1abc "2 def" "3 ghi" 1abc "2 def" "3 ghi" v1 equals 1abc v2 equals "2 def" v3 equals "3 ghi" C:\Users\joeco>echo_3params 1abc '2 def' "3 ghi" 1abc '2 def' v1 equals 1abc v2 equals '2 v3 equals def' C:\Users\joeco>
FOR %%A IN (%*) DO ( REM Now your batch file handles %%A instead of %1 REM No need to use SHIFT anymore. ECHO %%A )
这将循环播放批处理参数(%*),或者引用它们,然后回显每个参数.
我写了一个简单的read_params脚本,可以作为函数(或外部.bat
)调用,并将所有变量放入当前环境中.它不会修改原始参数,因为正在call
使用原始参数的副本编辑该函数.
例如,给定以下命令:
myscript.bat some -random=43 extra -greeting="hello world" fluff
myscript.bat
调用函数后能够使用变量:
call :read_params %* echo %random% echo %greeting%
这是功能:
:read_params if not %1/==/ ( if not "%__var%"=="" ( if not "%__var:~0,1%"=="-" ( endlocal goto read_params ) endlocal & set %__var:~1%=%~1 ) else ( setlocal & set __var=%~1 ) shift goto read_params ) exit /B
限制
无法加载没有值的参数,例如-force
.你可以使用,-force=true
但我想不出一种方法来允许空白值,而不知道提前没有值的参数列表.
更新日志
2016年2月18日
不再需要延迟扩张
现在通过查找-
参数之前使用其他命令行参数.
要在命令行中引用set变量,您需要使用它%a%
,例如:
set a=100 echo %a% rem output = 100
注意:这适用于Windows 7专业版.
受@Jon 在其他地方给出的答案的启发,我设计了一种更通用的算法来提取命名参数,可选值和开关。
让我们说我们要实现一个实用程序foobar
。它需要一个初始命令。它具有一个可选参数--foo
,该参数带有一个可选值(当然不能为另一个参数)。如果缺少该值,则默认为default
。它还具有一个可选参数--bar
,该参数采用必需的值。最后,它可以--baz
带有不允许值的标志。哦,这些参数可以按任何顺序排列。
换句话说,它看起来像这样:
foobar[--foo [ ]] [--bar ] [--baz]
这是一个解决方案:
@ECHO OFF SETLOCAL REM FooBar parameter demo REM By Garret Wilson SET CMD=%~1 IF "%CMD%" == "" ( GOTO usage ) SET FOO= SET DEFAULT_FOO=default SET BAR= SET BAZ= SHIFT :args SET PARAM=%~1 SET ARG=%~2 IF "%PARAM%" == "--foo" ( SHIFT IF NOT "%ARG%" == "" ( IF NOT "%ARG:~0,2%" == "--" ( SET FOO=%ARG% SHIFT ) ELSE ( SET FOO=%DEFAULT_FOO% ) ) ELSE ( SET FOO=%DEFAULT_FOO% ) ) ELSE IF "%PARAM%" == "--bar" ( SHIFT IF NOT "%ARG%" == "" ( SET BAR=%ARG% SHIFT ) ELSE ( ECHO Missing bar value. 1>&2 ECHO: GOTO usage ) ) ELSE IF "%PARAM%" == "--baz" ( SHIFT SET BAZ=true ) ELSE IF "%PARAM%" == "" ( GOTO endargs ) ELSE ( ECHO Unrecognized option %1. 1>&2 ECHO: GOTO usage ) GOTO args :endargs ECHO Command: %CMD% IF NOT "%FOO%" == "" ( ECHO Foo: %FOO% ) IF NOT "%BAR%" == "" ( ECHO Bar: %BAR% ) IF "%BAZ%" == "true" ( ECHO Baz ) REM TODO do something with FOO, BAR, and/or BAZ GOTO :eof :usage ECHO FooBar ECHO Usage: foobar ^[--foo [^ ]] [--bar ^ ] [--baz] EXIT /B 1
使用SETLOCAL
以便变量不会逸出到调用环境中。
SET FOO=
如果有人在调用环境中定义了变量,请不要忘记初始化变量等。
使用%~1
删除引号。
使用IF "%ARG%" == ""
而不是IF [%ARG%] == []
因为[
并且]
不玩游戏时,所有值都以空格结尾。
即使您SHIFT
位于一个IF
块中,诸如的当前arg %~1
也不会更新,因为它们是在IF
解析时确定的。您可以在块中使用%~1
和,但是由于您有个,因此会造成混淆。为了清楚起见,您可以将放在方框的末尾,但这可能会迷失和/或使人们感到困惑。因此,“捕获” 并在块外进行似乎是最好的。%~2
IF
SHIFT
SHIFT
%~1
%~1
您不想使用参数代替另一个参数的可选值,因此必须选中IF NOT "%ARG:~0,2%" == "--"
。
仅SHIFT
在使用其中一个参数时要小心。
重复的代码SET FOO=%DEFAULT_FOO%
令人遗憾,但替代方法是IF "%FOO%" == "" SET FOO=%DEFAULT_FOO%
在该IF NOT "%ARG%" == ""
块之外添加一个外部代码。然而,因为这仍然是内部IF "%PARAM%" == "--foo"
块,该%FOO%
值将进行了评估,你曾经进入前挡设置,所以你永远不会检测到两个的--foo
参数存在,也该%FOO%
值不见了。
请注意,ECHO Missing bar value. 1>&2
将错误消息发送到stderr。
想要Windows批处理文件中的空白行吗?您必须使用ECHO:
其中之一。
制作一个新的批处理文件(例如:openclass.bat),并将此行写入文件中:
java %~n1
然后将批处理文件放在(例如)system32文件夹中,转到您的Java类文件,右键单击“属性”,“打开方式为...”,然后找到您的批处理文件,将其选中,就是这样...
这个对我有用。
PS:关闭Java类时,找不到关闭cmd窗口的方法。目前...