Teil 1: Allgemeine Problemstellungen

Shell Scripting unter Windows

Befehlsergebnis als Errorlevel festhalten

Ein Grundprinzip von Windows Shell ist das Setzen der Variablen errorlevel nach jeder Befehlsauführung. So sind Sie in der Lage festzustellen, ob ein Kommando fehlerfrei ausgeführt wurde. Problematisch wird es immer dann, wenn das Kommando zwar ohne Fehler abgearbeitet wurde, aber dennoch nicht das gewünschte Ergebnis liefert.

Als Beispiel dient das Kommando tasklist. Mit Hilfe von tasklist soll festgestellt werden, ob auf einem bestimmten Computer ein Prozess ausgeführt wird. Dazu wird mit der Option /s das gewünschte System angegeben und als Suchfilter mit der Option /fi der gesuchte Prozessname definiert.

C:\tmp>tasklist /FI "imagename eq cmd.exe"
Abbildname PID Sitzungsname Sitz.-Nr. Speichernutzung
========== ================ ========= ===============
cmd.exe 2088 Console 0 1.404 K
C:\tmp>

Ganz gleich, ob cmd.exe auf der Maschine „blechbox“ noch ausgeführt wird oder nicht, wir erhalten in jedem Fall einen Errorlevel von 0, da das Kommando selbst ja fehlerfrei ausgeführt wurde. Das folgende Kommando verdeutlicht diesen Sachverhalt.

C:\tmp>tasklist /FI "imagename eq not_here.exe"
INFORMATION: Es werden keine Tasks mit den angegebenen Kriterien ausgeführt.

C:\tmp>echo %errorlevel%
0

C:\tmp>

Ein anderer Wert als 0 für den Errorlevel würde sich nur dann ergeben, wenn ein wirklicher Laufzeitfehler auftritt. Um das zu verdeutlichen, geben wir im nachfolgenden Beispiel absichtlich eine ungültige Option an.

C:\tmp>tasklist /FX "imagename eq cmd.exe"
FEHLER: Argument/Option ungültig - '/FX'.
Geben Sie "TASKLIST /?" ein, um die Syntax anzuzeigen.

C:\tmp>echo %errorlevel%
1

Wie lässt sich nun innerhalb eines Batches feststellen, ob ein bestimmter Prozess noch ausgeführt wird oder nicht? Dazu wird die Ausgabe von tasklist per Piping an den Filter find (alternativ ist auch findstr möglich) weitergereicht. Wir nutzen hier die Tatsache, dass bei einem gefundenen Prozess der Name des Prozesses auch in der Ausgabe auftaucht. Wird der Prozess nicht gefunden, erhalten Sie nur eine Mitteilung, dass kein entsprechender Task ausgeführt wird. Über die Verwendung von find erhalten wir sehr wohl einen passenden Errorlevel. Wird der Prozessname nicht gefunden, liefert find einen Errorlevel von 1, bei Erfolg einen Wert von 0.

C:\tmp>tasklist /FI "imagename eq cmd.exe" /NH | find /i
"cmd.exe" > nul
C:\tmp>echo %errorlevel%
0
C:\tmp>tasklist /FI "imagename eq nixda.exe" /NH | find
/i "nixda.exe" > nul
C:\tmp>echo %errorlevel%
1
C:\tmp>

Dieser Ansatz lässt sich für alle Shellbefehle nutzen, die zwar fehlerfrei ablaufen, aber auch auf ein bestimmtes Ergebnis getestet werden sollen. Die Ausgabe selbst wird für das Zuweisen an die Variable errorlevel nicht benötigt, daher erfolgt eine Umleitung in das Null-Device.

Sehr gut kombinierbar ist dieser Ansatz auch mit der Befehlsverkettung über die Operatoren && bzw. ||. So wird ein nachfolgendes Kommando nur dann ausgeführt, wenn der Prozess noch (oder eben nicht mehr) läuft.