gpt4 book ai didi

batch-file - 解析包含 = 的命令行参数

转载 作者:行者123 更新时间:2023-12-02 11:29:36 24 4
gpt4 key购买 nike

使用批处理文件多年后,我惊讶地发现等号“=”被视为参数分隔符。

给出这个测试脚本:

echo arg1: %1
echo arg2: %2
echo arg3: %3

和调用:

test.bat a=b c

输出是:

arg1: a
arg2: b
arg3: c

为什么会这样以及如何避免?我不希望脚本的用户考虑到这个怪癖并引用“a=b”,这是违反直觉的。

此批处理脚本在 Windows 7 上运行。

=====编辑=====

更多背景知识:我在编写 bat 文件来启动 Java 应用程序时遇到了这个问题。我想使用 bat 文件中的一些参数,然后将其余的传递给 java 应用程序。所以我的第一次尝试是执行 shift 然后重建 args 列表(因为 %* 不受 shift 的影响)。它看起来像这样,就在那时我发现了问题:

rem Rebuild the args, %* does not work after shift
:args
if not "%1" == "" (
set ARGS=!ARGS! %1
shift
goto args
)

下一步是不再使用移位,而是通过从 %* 一次删除一个字符直到遇到空格来手动实现移位:

rem Remove the 1st arg if it was the profile
set ARGS=%*
if not "%FIRST_ARG%" == "%KNOA_PROFILE%" goto remove_first_done
:remove_first
if not defined ARGS goto remove_first_done
if "%ARGS:~0,1%" == " " goto remove_first_done
set ARGS=%ARGS:~1%
goto remove_first
:remove_first_done

但这很丑陋,并且在某些我没有考虑过的情况下仍然可能会失败。所以最后我决定写一个Java程序来处理参数解析!就我而言,这很好,因为我正在启动服务器,并且额外的 java 调用的惩罚是最小的。有时你最终所做的事情令人难以置信。

您可能想知道为什么我不处理 Java 应用程序本身中的参数?答案是我希望能够传递像 -Xmx 这样的 JVM 选项,这些选项必须在调用 java 之前处理。

最佳答案

我猜它这样做是为了让 /param=data/param data

我不知道有什么技巧可以解决这个愚蠢的(可能是设计造成的)解析问题,但我能够想出一个 super 丑陋的解决方法:

@echo off
setlocal ENABLEEXTENSIONS
set param=1
:fixnextparam
set p=
((echo "%~1"|find " ")>nul)||(
call :fixparam %param% "%~1" "%~2" %* 2>nul
)
if "%p%"=="" (set "p%param%=%1") else shift
shift&set /A param=%param% + 1
if not "%~1"=="" goto fixnextparam

echo.1=%p1%
echo.2=%p2%
echo.3=%p3%
echo.4=%p4%
echo.5=%p5%
goto:EOF


:fixparam
set p%1=
for /F "tokens=4" %%A in ("%*") do (
if "%%~A"=="%~2=%~3" set p=!&set "p%1=%%A"
)
goto:EOF

当我执行 test.cmd foo=bar baz "fizzuzz"w00t 时,我得到:

1=foo=bar
2=baz
3="fizz buzz"
4=w00t
5=

这样做的问题当然是你不能进行 %~dp1 风格的变量扩展。不可能先执行 call :mylabel %* 然后使用 %1,因为 call :batchlabel 具有相同的参数解析问题!

如果您确实需要 %~dp1 处理,您可以使用 WSH/batch hybrid黑客:

@if (1==1) @if(1==0) @ELSE
@echo off
@SETLOCAL ENABLEEXTENSIONS
if "%SPECIALPARSE%"=="*%~f0" (
echo.1=%~1
echo.2=%~2
echo.3=%~3
echo.4=%~4
echo.5=%~5
) else (
set "SPECIALPARSE=*%~f0"
cscript //E:JScript //nologo "%~f0" %*
)
@goto :EOF
@end @ELSE
w=WScript,wa=w.Arguments,al=wa.length,Sh=w.CreateObject("WScript.Shell"),p="";
for(i=0;i<al;++i)p+="\""+wa.Item(i)+"\" ";
function PipeStream(i,o){for(;!i.AtEndOfStream;)o.Write(i.Read(1))}
function Exec(cmd,e){
try{
e=Sh.Exec(cmd);
while(e.Status==0){
w.Sleep(99);
PipeStream(e.StdOut,w.StdOut);
PipeStream(e.StdErr,w.StdErr);
}
return e.ExitCode;
}catch(e){return e.number;}
}
w.Quit(Exec("\""+WScript.ScriptFullName+"\" "+p));
@end

关于batch-file - 解析包含 = 的命令行参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7247195/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com