2009-04-17 11 views
34

Nell'esempio seguente, desidero chiamare un file batch figlio da un file batch principale e passare tutti i parametri rimanenti al figlio.C'è un modo per indicare gli ultimi n parametri in un file batch?

C:\> parent.cmd child1 foo bar 
C:\> parent.cmd child2 baz zoop 
C:\> parent.cmd child3 a b c d e f g h i j k l m n o p q r s t u v w x y z 

All'interno parent.cmd, ho bisogno di mettere a nudo% 1 fuori dalla lista dei parametri e passare solo i restanti parametri allo script bambino.

set CMD=%1 
%CMD% <WHAT DO I PUT HERE> 

Ho studiato utilizzando SHIFT con% *, ma non funziona. Mentre SHIFT sposta i parametri posizionali di 1,% * fa ancora riferimento ai parametri originali.

Qualcuno ha qualche idea? Dovrei semplicemente rinunciare e installare Linux?

+0

duplicato esatto? http://stackoverflow.com/questions/382587/how-to-get-batch-file-parameters-from-nth-position-on –

+0

A questa domanda è stato risposto con un codice che non ha funzionato. Ho aggiunto delle affermazioni alla mia domanda per aiutare a chiarire, e sembra che ho ricevuto una risposta solida da Johannes. – Dave

+0

Oh, a proposito, quando si chiamano batch da altri batch, tutti i camerieri usano la chiamata. In caso contrario, il file batch chiamante non verrà eseguito ulteriormente dopo l'uscita del batch chiamato. (Può o non può essere rilevante qui, solo alcune buone pratiche :-)) – Joey

risposta

62

%* si espanderà sempre a tutti i parametri originali, purtroppo. Ma è possibile utilizzare il seguente frammento di codice per costruire una variabile contenente tutti, ma il primo parametro:

rem throw the first parameter away 
shift 
set params=%1 
:loop 
shift 
if [%1]==[] goto afterloop 
set params=%params% %1 
goto loop 
:afterloop 

Penso che possa essere fatto più breve, anche se ... non scrivo questo genere di cose, molto spesso :)

Dovrebbe funzionare, comunque.

+0

Come ha detto Tbee, questo non funziona se hai '=' nei tuoi argomenti rimanenti. Sembra che l'unico vero modo per risolverlo sia scrivere un programma per estrarre correttamente i tuoi argomenti - la shell cmd è troppo sciatta. –

+3

Questo approccio ha esito negativo se si dispone di assegnazioni nei parametri, ad es. "A = b". Quindi otterrai due parametri separati "a" e "b", perdendo il =. – Tbee

+2

In tal caso, cita l'argomento. 'cmd' considera anche alcuni altri caratteri come separatori di argomenti, come'; 'o', '. – Joey

14

Ecco un approccio one-line utilizzando il "per" il comando ...

for /f "usebackq tokens=1*" %%i in (`echo %*`) DO @ set params=%%j 

Questo comando assegna il primo parametro su "i" e il resto (indicato con '*') sono assegnati a " j ", che viene quindi utilizzato per impostare la variabile" params ".

+0

Questo fallisce quando il primo argomento contiene uno spazio (quotato), ad esempio "primo argomento" secondo terzo "imposta i parametri su" argomento "secondo terzo" – EM0

5

Si può effettivamente solo fare questo:

%* 

Se questo è l'unica cosa sulla linea, poi che si espande ad avere il primo parametro essere il comando eseguito, con tutti gli altri parametri passati ad esso . :)

1

Un altro modo (quasi la stessa di Alxander Bird) senza eseguire ECHO in una subshell:

FOR /F "usebackq tokens=1*" %%I IN ('%*') DO SET params=%%J 

così, la linea

%CMD% <WHAT DO I PUT HERE> 

sarà simile:

FOR /F "usebackq tokens=1*" %%I IN ('%*') DO %CMD% %%J 

il problema è che se i parametri includono punture quotate con spazi interni, cmd.exe li analizzerà in modo appropriato per l'utilizzo di un s argomenti numerati (% 1), ma FOR ignorerà le virgolette. In questo caso specifico, danneggerà se il primo parametro include uno spazio o più, il che è del tutto possibile, considerando% CMD% può essere, ad esempio, "C: \ Programmi \ Internet Explorer \ iexplore.exe".

Quindi, ecco un'altra risposta.

7

la linea

%CMD% <WHAT DO I PUT HERE> 

diventa punto:

(
SETLOCAL ENABLEDELAYEDEXPANSION 
SET Skip=1 

FOR %%I IN (%*) DO IF !Skip! LEQ 0 ( 
     SET params=!params! %%I 
    ) ELSE SET /A Skip-=1 
) 
(
ENDLOCAL 
SET params=%params% 
) 
%CMD% %params% 

naturalmente, è possibile impostare Vai a qualsiasi numero di argomenti.

0

Anche se in realtà la 'per la' soluzione è superiore in molte circostanze, di qualcosa di semplice io spesso basta salvare e spostare gli altri argomenti di distanza, quindi utilizzare %* come al solito (praticamente la stessa strategia spesso funziona per $* o [email protected] in {,ba,da,k,*}sh):

esempio:

:: run_and_time_me.cmd - run a command with the arguments passed, while also piping 
::      the output through a second passed-in executable 

@echo off 

set run_me=%1 
set pipe_to_me=%2 
shift 
shift 

:: or 
:: set run_me=%1 
:: shift 
:: set pipe_to_me=%1 
:: shift 

%run_me% %* | %pipe_to_me% 

in ogni caso, ho visto la domanda è stata a lungo risposto, ma pensato che avrei dr nei miei due centesimi perché era qualcosa che non vedevo, e perché era la risposta di cui avevo bisogno quando finalmente mi sono imbattuto in alcuni anni fa ... e sono andato "oh ... duh". :)

+1

spostamento non influenza% * quindi questo passa * tutti * gli argomenti originali a% run_me%, compresi% 1 e% 2. Come la risposta accettata dice "% * si espanderà sempre su tutti i parametri originali, purtroppo." – Naaff

0

Mi sono imbattuto in questa domanda mentre stavo affrontando un problema simile, ma l'ho risolto utilizzando un approccio diverso. Invece di ricreare la linea di input usando un loop (come nella risposta di @Joey) ho semplicemente rimosso il primo parametro dalla stringa di input.

set _input=%* 
set params=!_input:%1 =! 
call OTHER_BATCH_FILE.cmd %params% 

Ovviamente, questo presuppone che tutti i parametri siano diversi.

Problemi correlati