在shift之后使用`%*`

我知道在一个Windowsbatch file中, %*扩展为所有的命令行参数,并且这个shift会移动编号的命令行参数%1%2等,但不会改变%*的内容。

如果我想要一个反映shift效果的%*版本,我该怎么办? 我知道我可以在转换之后说出%1 %2 %3 %4 %5 %6 %7 %8 %9 ,但这似乎是愚蠢的,而且可能有危险,这就使我有一定数量的争论。

虽然这不是一个python特有的问题,但它可能有助于理解我想要这种行为的原因是我必须编写一个batch fileSelectPython.bat来预先configuration某些环境variables,以便浏览babel我有不同的Python发行版(您必须以某种方式设置%PYTHONHOME%%PYTHONPATH%%PATH% ,然后才能调用Python二进制文件并确信您将获得正确的发行版)。 我当前的脚本适用于设置这些variables,但我希望能够在一行中调用它 Python – 例如:

 SelectPython C:\Python35 pythonw.exe myscript.py arg1 arg2 arg3 ... 

理想情况下,我希望我的batch file使用shift来“吃”第一个参数,相应地处理它并设置环境,然后自动链接执行由其余参数形成的string。 这个原理类似于env在posix系统中包装命令的方式:

 env FOO=1 echo $FOO # wrap the `echo` command to be executed in the context of specified environment settings 

到目前为止,我有这个 – 最后一行是问题所在:

 @echo off set "LOC=%CD% if not "%~1" == "" set "LOC=%~1 if exist "%LOC%\python.exe" goto :Success echo "python.exe not found in %LOC%" goto :eof :Success :: Canonicalize the resulting path: pushd %LOC% set "LOC=%CD% popd :: Let Python know where its own files are: set "PYTHONHOME=%LOC% set "PYTHONPATH=%LOC%;%LOC%\Lib\site-packages :: Put Python's location at the beginning of the system path if it's not there already: echo "%PATH%" | findstr /i /b /c:"%PYTHONHOME%" > nul || set "PATH=%PYTHONHOME%;%PYTHONHOME%\Scripts;%PATH% :: Now execute the rest: shift if "%~1" == "" goto :eof %1 %2 %3 %4 %5 %6 %7 %8 %9 :: This is unsatsifactory - what if there are more than 9 arguments? 

更新:感谢斯蒂芬我的工作解决scheme现在有以下更改结束部分:

 :: Now execute the rest of the arguments, if any: shift if @%1 == @ goto :eof set command= :BuildCommand if @%1 == @ goto :CommandFinished set "command=%command% %1" shift goto :BuildCommand :CommandFinished %command% 

建立你自己的“%*”(我把它命名为%params% ):

 set "params=" :build if @%1==@ goto :cont shift set "params=%params% %1" goto :build :cont echo params are %params% 

只是从Mofi的例子略有变化,但通过使用批处理文件名作为所有参数的一部分,并保护以防止删除任何额外的参数,然后删除批处理文件和参数1。

 @echo off set all_args=%~f0%* call set exe_arg=%%all_args:%~f0%1 =%% echo %exe_arg% pause 

最终,如果你想使用延迟扩展来节省几厘秒,那么使用CALL或使用SHIFT会更快。

 @echo off setlocal enabledelayedexpansion set all_args=%~f0%* set exe_arg=!all_args:%~f0%1 =! echo %exe_arg% 

批量代码根据Squashman的想法

 @echo off setlocal EnableDelayedExpansion set "LOC=%1" set "AllParameters=%*" set "AllButFirst=!AllParameters:%LOC% =!" echo Remaining: %AllButFirst% endlocal pause 

这产生了

 "C:\Program Files\Oh god why did I install it here\Python27" python -c "print 'hello'" 

预期的产出

 python -c "print 'hello'" 

此代码的问题:如果目录路径(第一个参数)在另一个参数上也被找到,则它也会从另一个参数中删除,因为替换会删除所有搜索到的字符串,而不是首次出现。