在批处理文件参数中保留“=”(相等)字符

时间:2013-12-13 17:25:42

标签: windows batch-file

我写了一个批处理文件来启动一个应用程序(该应用程序不是我的,我无法修改它)。批处理文件本身接受一些参数。该应用程序接受其他参数。批处理文件使用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跳过的参数)。

有没有办法只传递最后一个参数并保留“=”符号?

4 个答案:

答案 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)

取自https://blogs.oracle.com/quinn/a-little-trick-with-windows-bat-scripts-argument-processing-and-equals-signs

: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-这是我所见过的最完整的实现之一。而且比提供的其他答案要全面得多。