我写了一个批处理文件来启动一个应用程序(该应用程序不是我的,我无法修改它)。批处理文件本身接受一些参数。该应用程序接受其他参数。批处理文件使用SHIFT消耗其所有选项,然后使用正确的环境启动应用程序并将其余参数传递给应用程序。调用批处理文件的示例:
script.bat -opt-1 -opt-2 /opt-a /opt-b=value
在示例中,script.bat使用“-opt-1”和“-opt-2”。最后,它必须使用参数“/ opt-a”和“/ opt-b = value”调用原始应用程序。应用程序期望最后一个参数中的“=”符号,我无法更改它。当我直接从命令行调用应用程序时,它运行良好。
但是当我从脚本中调用它时,应用程序会收到“/ opt-b = value”的两个参数:“/ opt-b”和“value”。如果我在调用应用程序时使用“%*”,则会保留“=”符号,但会传递所有参数(包括使用SHIFT跳过的参数)。
有没有办法只传递最后一个参数并保留“=”符号?
答案 0 :(得分:5)
以这种方式致电script.bat
:
script.bat -opt-1 -opt-2 /opt-a "/opt-b=value"
并在script.bat
内,以这种方式调用应用程序:
rem Consume -opt-1
shift
rem Consume -opt-2
shift
rem Call the application
application %1 %~2
编辑:对评论的回复
确定。让我们详细了解这个问题。
下面的script.bat文件:
@echo off
rem Consume -opt-1
shift
rem Consume -opt-2
shift
rem Call the application
ECHO application %1 %~2
(请注意ECHO
命令)正确地“调用”应用程序,第二个参数包括等号,当第四个参数用引号括起来时,如下一个屏幕输出显示:
C:\> script.bat -opt-1 -opt-2 /opt-a "/opt-b=value"
application /opt-a /opt-b=value
但是,如果应用程序 是一个批处理文件 ,那么它会遇到与原始script.bat文件相同的问题。你说“当我直接从命令行调用应用程序时,它运行良好”。嗯,这不是真的:
C:\> type application.bat
@echo off
rem ** application.bat **
echo 1: %1
echo 2: %2
echo 3: %3
echo 4: %4
C:\> application /opt-a /opt-b=value
1: /opt-a
2: /opt-b
3: value
4:
除了空格和制表符之外,批处理文件的参数可以用逗号,分号或等号分隔。这样,如果应用程序期望“The”=“在最后一个参数中签名”,则应用程序无法成为批处理文件,并且无法使用批处理文件而不是应用程序。
您是否使用真实的应用程序测试了此解决方案?
答案 1 :(得分:1)
FOR /f "tokens=1*" %%x IN ("%*") DO ECHO application %%y
其中1
是要跳过的参数数量。
测试...主.bat
(q20572424.bat)
@ECHO OFF
SETLOCAL
ECHO master[%*]
FOR /f "tokens=2*" %%x IN ("%*") DO CALL q20572424a.bat %%y
FOR /f "tokens=1*" %%x IN ("%*") DO CALL q20572424a.bat %%y
FOR /f "tokens=*" %%x IN ("%*") DO CALL q20572424a.bat %%x
GOTO :EOF
子公司.bat
(q20572424a.bat)
@ECHO OFF
SETLOCAL
ECHO slave=[%*]
FOR /f "tokens=2*" %%x IN ("%*") DO CALL q20572424b.bat %%y
FOR /f "tokens=1*" %%x IN ("%*") DO CALL q20572424b.bat %%y
FOR /f "tokens=*" %%x IN ("%*") DO CALL q20572424b.bat %%x
GOTO :EOF
第二个子公司.bat
(q20572424b.bat)
@ECHO OFF
SETLOCAL
ECHO subslave=[%*]
GOTO :EOF
结果:
从正在运行q20572424 -opt-1 -opt-2 /opt-a /opt-b=value
master[-opt-1 -opt-2 /opt-a /opt-b=value]
slave=[/opt-a /opt-b=value]
subslave=[]
subslave=[/opt-b=value]
subslave=[/opt-a /opt-b=value]
slave=[-opt-2 /opt-a /opt-b=value]
subslave=[/opt-b=value]
subslave=[/opt-a /opt-b=value]
subslave=[-opt-2 /opt-a /opt-b=value]
slave=[-opt-1 -opt-2 /opt-a /opt-b=value]
subslave=[/opt-a /opt-b=value]
subslave=[-opt-2 /opt-a /opt-b=value]
subslave=[-opt-1 -opt-2 /opt-a /opt-b=value]
这似乎是正确的。在每种情况下,子批次逐字接收参数;每次调用删除的前导参数数量为2,1.0。
W7HP - 适合我!
答案 2 :(得分:0)
:recurse
for /F "tokens=1*" %%a in ("%*") do (
rem do something
...
if NOT x%%b==x call :recurse %%b
)
答案 3 :(得分:0)
看看:https://github.com/frossm/getopt.btm-这是我所见过的最完整的实现之一。而且比提供的其他答案要全面得多。