在`shift`之后使用`%*`

时间:2015-11-30 17:59:05

标签: windows batch-file

据我所知,在Windows批处理文件中,%*扩展为所有命令行参数,shift移动编号的命令行参数%1,{{1}等等,但更改%2的内容。

如果我想要 %*版本反映%*的效果,我该怎么办?我知道我可以在转移之后说shift,但这似乎很愚蠢且有潜在危险,这限制了我固定数量的论点。

虽然这不是特定于python的问题,但我可能有必要了解我想要这种行为的原因是我必须编写一个批处理文件%1 %2 %3 %4 %5 %6 %7 %8 %9来预先配置某些环境变量,为了导航我所拥有的不同Python发行版的babel(您必须以某种方式设置SelectPython.bat%PYTHONHOME%%PYTHONPATH%才能调用Python二进制文件并且相信您会得到正确的发行版)。我当前的脚本适用于设置这些变量,但我希望能够在一行中将它称为 Python - 例如:

%PATH%

理想情况下,我希望我的批处理文件使用SelectPython C:\Python35 pythonw.exe myscript.py arg1 arg2 arg3 ... “吃掉”第一个参数,相应地处理它并设置环境,然后自动链式执行其余参数形成的字符串。该原则类似于shift在posix系统中包装命令的方式:

env

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

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

更新:感谢Stephan我的工作解决方案现在有以下更改的结尾部分:

@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?

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

与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%

答案 2 :(得分:1)

根据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'"

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