2016-03-18 54 views
6

Supponendo che sia presente un file batch (chiamante) che esegue un altro file batch (chiamato), è necessario utilizzare il comando call per tornare al chiamante dopo che il destinatario ha terminato l'esecuzione. Ecco un esempio:Perché non c'è bisogno che `call` ritorni dallo script batch chiamato che è coinvolto in una pipe?

caller.bat:

echo Calling another script... 
call callee.bat 
echo Returned from callee... 

callee.bat (nella stessa posizione) :

echo Being called from caller... 

L'uscita sarà presente (omettendo gli echi di comando) , mostrando che l'esecuzione è tornata come previsto:

Calling another script... 
    Being called from caller... 
Returned from callee... 

Se il comando call è stato respinto nel chiamante, l'output sarà:

Calling another script... 
    Being called from caller... 

Ma non appena il chiamato è coinvolto in un tubo (|), non vi è alcuna differenza nel fatto che venga utilizzato o meno il comando call. Per esempio:

caller.bat (il chiamato rimane invariato) :

echo Calling another script... 
break | callee.bat 
echo Returned from callee... 

l'uscita sarà presente, anche se non c'è alcun comando call.

Calling another script... 
    Being called from caller... 
Returned from callee... 

Qual è il motivo di questo comportamento, ciò che provoca l'esecuzione per tornare al chiamante qui?

+1

La domanda per me c'è qualche differenza tra 'break | command' e' call command'? Controlla anche questo 'set a = b'; 'set b = c'; 'break | echo %%% a %%%'. E ... l'output è 'c'. In entrambi i casi si crea un nuovo sotto-contesto del cmd. Possono essere alcuni stati del cmd conservati quando si usa 'call'? – npocmaka

+1

Oh. 'REM',' SE' e 'FOR' si comportano in modo diverso quando vengono convogliati e quando vengono richiamati, ma questo è rahter die al parsing. – npocmaka

+0

Hmm ... oltre al trasferimento dati da _STDOUT_ a _STDIN_ di tubi, sembra che non ci sia alcuna differenza; anche 'cmd/C callee.bat' ritorna al chiamante; sì, 'rem',' if' e 'for' sono speciali, perché ricordo che sono riconosciuti prima di altri comandi durante il processo di analisi ... – aschipfl

risposta

6

Ci sono due modi per chiamare un altro file batch da quella chiamante (principale file): call callee.bat e cmd /C callee.bat; la differenza è che call esegue l'altro file batch nello stesso contesto del programma chiamante, quindi condividono le stesse variabili di ambiente e un altro stato, mentre cmd /C esegue l'altro file Batch in un contesto completamente separato. Proprio come una nota personale, che ho usato per citarne sottoprogramma interno il file batch richiamato tramite call, e subroutine esterna quello invocato via cmd /C (e sovrapposizione il file batch direttamente invocato senza callcmd /C, che eredita il comportamento e il contesto del file batch del chiamante).

Nell'esecuzione di un tubo, entrambi i lati del tubo vengono eseguiti tramite un cmd /C, quindi entrambi i lati vengono richiamati come subroutine esterne. In questo modo, se un qualsiasi lato di una pipe è un file Batch.BAT, esso ritorna al programma chiamante quando termina.

Lo stesso comportamento si verifica in un file batch chiamato in un comando for /F ed esatto per lo stesso motivo; for /F %%a in ('calle.bat') do ...