Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using `%*` after `shift`

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

What do I do if I want a version of %* that does reflect the effect of shift? I understand I could just say %1 %2 %3 %4 %5 %6 %7 %8 %9 after shifting but it seems stupid and potentially dangerous that that 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 behaviour is that I've had to write a batch file SelectPython.bat that pre-configures certain environment variables, in order to navigate the babel of different Python distros I have (you have to set %PYTHONHOME%, %PYTHONPATH% and %PATH% in certain ways before you can call the Python binary and have confidence that you'll get the right distro). My current script works fine for setting these variables, but I would like to be able to call it and Python in one line - e.g.:

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

Ideally I want my batch file to use shift to "eat" the first argument, process it accordingly and set up the environment, and then just automatically chain-execute the string formed by rest of the arguments. The principle is analogous to the way env wraps commands in 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 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'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?

UPDATE: Thanks to Stephan my working solution now has the following altered end-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%
like image 627
jez Avatar asked Nov 30 '15 17:11

jez


1 Answers

build 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%
like image 197
Stephan Avatar answered Oct 06 '22 00:10

Stephan