2016-03-18 12 views
6

Angenommen, es gibt eine Batch-Datei (Aufrufer), die eine andere Batch-Datei (callee) ausführt, muss der Befehl call verwendet werden, um zum Aufrufer zurückzukehren, nachdem der Aufrufer die Ausführung beendet hat. Hier ein Beispiel:Warum muss `call` nicht vom aufgerufenen Batch-Skript zurückgegeben werden, das an einer Pipe beteiligt ist?

caller.bat:

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

callee.bat (an derselben Stelle) :

echo Being called from caller... 

Der Ausgang wird dieser (Weglassen der Befehl Echos) zeigt an, dass die Ausführung wie erwartet zurückgegeben wurde:

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

Wenn der call Befehl in dem Anrufer abgewiesen worden war, würde der Ausgang sein:

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

Aber sobald der Angerufene in einem Rohr beteiligt ist (|), gibt es keinen Unterschied, ob der call Befehl verwendet wird oder nicht. Zum Beispiel:

caller.bat (die Angerufene bleibt unverändert) :

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

Der Ausgang wird dies, obwohl es kein call Befehl.

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

Was ist der Grund für dieses Verhalten, was die Ausführung hier, um den Anrufer zurück verursacht?

+1

Die Frage für mich ist, gibt es einen Unterschied zwischen 'brechen | Befehl' und' call command'? Überprüfe auch dieses "set a = b"; 'set b = c'; 'break | echo %%% a %%%'. Und ... die Ausgabe ist 'c'. In beiden Fällen erstellen Sie einen neuen Unterkontext des cmd. Können einige Zustände des Cmd beibehalten werden, wenn 'call' verwendet wird? – npocmaka

+1

Oh. "REM", "IF" und "FOR" verhalten sich unterschiedlich, wenn sie piped sind und wenn sie CALLed sind, aber das ist rarer sterben für das Parsing. – npocmaka

+0

Hmm ... neben der Datenübertragung von _STDOUT_ zu _STDIN_ von Rohren scheint es überhaupt keinen Unterschied zu geben; selbst 'cmd/C callee.bat' kehrt zum Aufrufer zurück; Ja, 'rem',' if' und 'for' sind speziell, weil ich mich erinnere, dass sie früher als andere Befehle während des Parsingprozesses erkannt wurden ... – aschipfl

Antwort

6

Es gibt zwei Möglichkeiten, eine andere Batch-Datei aus dem Anrufer ein nennen (Haupt Datei): call callee.bat und cmd /C callee.bat; Der Unterschied ist, dass call die andere Batch-Datei im selben Kontext des aufrufenden Programms ausführen, so dass sie die gleichen Umgebungsvariablen und einen anderen Status teilen, während cmd /C die andere Batch-Datei in einem vollständig getrennten Kontext ausführen. Genauso wie eine persönliche Note, benutzen ich internes Unterprogramm die Batch-Datei über call und externes Unterprogramm derjenige aufgerufen über cmd /C (und Overlay die Batch-Datei aufgerufen direkt ohne call noch cmd /C aufgerufen zu nennen, dass erbt Verhalten und Kontext der aufrufenden Batch-Datei).

Bei der Ausführung einer Leitung werden beide Seiten der Leitung über eine cmd /C ausgeführt, so dass beide Seiten als externe Unterroutinen aufgerufen werden. Wenn eine Seite einer Pipe eine Batch.BAT-Datei ist, kehrt sie auf diese Weise zum Aufruferprogramm zurück, wenn sie beendet wird.

Das gleiche Verhalten geschieht in einer callee Batch-Datei in einem for /F Befehl abgelegt, und aus dem gleichen Grund exaclty; for /F %%a in ('calle.bat') do ...

Verwandte Themen