Using `% *` after `shift`

I understand that in a batch file Windows %* expands to all command line arguments and that shift shifts the numbered command line arguments %1 , %2 , etc., but this does not change the contents of %* .

What should I do if I want the %* version to reflect the shift effect? I understand that I can just say %1 %2 %3 %4 %5 %6 %7 %8 %9 after the shift, but it seems silly and potentially dangerous that this limits me to a fixed number of arguments.

Although this is not a python-specific question, it may help to understand that the reason I want this behavior is that I had to write a SelectPython.bat batch file that preconfigures certain environment variables to go into babel of various distributions Python, I have (you must install %PYTHONHOME% , %PYTHONPATH% and %PATH% certain way before you can call the Python binary and make sure you get the correct distribution). My current script works fine for setting these variables, but I would like to be able to call it and Python on the same line - for example:

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

Ideally, I want my batch file to use shift to β€œeat up” the first argument, process it accordingly and set up the environment, and then simply automatically execute the chain formed by the rest of the arguments. The principle is similar to the env method of wrapping commands on posix systems:

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

So far I have this - the last line - this is where the problem is:

 @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 location at the beginning of the system path if it 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? 

UPDATE: Thanks to Stephan, my working solution now has the following modified final section:

 :: 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% 
+5
source share
3 answers

create your own "% *" (I named it %params% ):

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

A slight deviation from the Mofi example, but protects against the removal of any additional arguments, using the batch file name as part of all arguments, and then deletes the batch file and argument 1.

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

Ultimately, if you want to save a few centi seconds using Delayed Expansion, faster using CALL or using SHIFT.

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

Party code as per Squashman idea

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

It creates for

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

expected output

 python -c "print 'hello'" 

The problem with this code is: if the directory path (the first parameter) is also found on another parameter, it is also deleted from another parameter, because the substitution deletes all occurrences of the search string, not just the first occurrence.

+1
source

Source: https://habr.com/ru/post/1237119/


All Articles