GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Shell-Skript While-Schleife:[um eine Pipeline herum fehlt `]'

Der Fehler ist, dass Sie zuerst [ entfernen sollten da Sie den Exit-Status überprüfen möchten, verwenden Sie den Befehl direkt.

Die Wiki-Seiten des Tools Shellcheck haben dazu eine Erklärung (issue SC1014):

[ .. ] ist nicht Teil der Shell-Syntax wie if Aussagen. Es ist nicht gleichbedeutend mit Klammern in C-ähnlichen Sprachen, if (foo) { bar; } , und sollte nicht um zu testende Befehle gewickelt werden.

[ ist nur ein normaler Befehl, wie whoami oder grep , aber mit komischem Namen (siehe ls -l /bin/[ ). Es ist eine Abkürzung für test .

Wenn Sie den Beendigungsstatus eines bestimmten Befehls überprüfen möchten, verwenden Sie diesen Befehl direkt.

Wenn Sie die Ausgabe eines Befehls überprüfen möchten, verwenden Sie "$(..)" um seine Ausgabe zu erhalten, und verwenden Sie dann test oder [ /[[ um einen Zeichenfolgenvergleich durchzuführen:

Verwenden Sie auch ps aux | grep -q "[r]elayevent.sh" sodass Sie den Exit-Status im Hintergrund erhalten, anstatt irgendetwas auf stdout zu drucken .

Oder Sie können pgrep verwenden und leite seine Ausgabe an /dev/null weiter .

Verwenden Sie zuerst die zweite Bedingung, da dies für den letzten Fall effizienter ist.

Das endgültige Skript sieht also folgendermaßen aus:

#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh"   ; do

    sleep 3

    let COUNTER+=1

done

Oder

#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep  "[r]elayevent.sh" >/dev/null  ; do

    sleep 3

    let COUNTER+=1

done

Sie können keine Pipe innerhalb von [ ... ] haben . Es ist auch besser, pgrep zu verwenden als zu versuchen, die Ausgabe von ps zu parsen :

count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
    sleep 3
    count=$(( count + 1 ))
done

BSD-Systeme könnten pgrep -q ... verwenden statt pgrep ... >/dev/null um die tatsächliche Ausgabe von pgrep zu verwerfen , genau wie beim gewöhnlichen grep (uns interessiert nur der Exit-Status).

Beachten Sie, dass wir pgrep nicht einfügen Befehl innerhalb von [ ... ] . Das liegt daran, dass wir nicht an seiner Ausgabe interessiert sind, sondern nur an seinem Exit-Status. Mit [ ... ] Sie vergleichen normalerweise Zeichenfolgen oder Zahlen. Der [ ... ] führt zu einem Exit-Status, der null (wahr) oder ungleich null (falsch) ist, genau wie pgrep Ausführung.

Dies prüft jedoch nicht auf Sperrmechanismen, sondern nur darauf, ob ein bestimmter Prozess läuft oder nicht.

Wenn Sie versuchen, nur eine einzige Instanz eines Skripts zum Laufen zu bringen, dann ist es besser, so etwas zu tun (vorausgesetzt, der EXIT trap wird immer dann ausgeführt, wenn das Skript ordnungsgemäß beendet wird):

lockdir=dir.lock

if mkdir "$lockdir"; then
    trap 'rmdir "$lockdir"' EXIT
else
    echo 'Only one instance of this script allowed' >&2
    exit 1
fi

Mit einigen Versuchen und schlafen:

lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
    if mkdir "$lockdir"; then
        trap 'rmdir "$lockdir"' EXIT
        break
    else
        echo 'Locked. Sleeping...' >&2
        sleep 3
    fi

    count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
    echo 'Giving up.' >&2
    exit 1
fi

Verwandte:

  • Wie stelle ich sicher, dass nur eine Instanz eines Bash-Skripts ausgeführt wird?

Linux
  1. Wie kann man Umgebungsvariablen „exportiert“ in einem Shell-Skript bleiben lassen?

  2. In der Schleife gefangen? Awk While, Do While, For Loop, Break, Continue, Exit Beispiele

  3. Wie erhalte ich den Exit-Code des erzeugten Prozesses im erwarteten Shell-Skript?

  4. Beginnend für Schleife vom zweiten Element - Shell-Skript

  5. Wie kann man bei der Verwendung von printf Sonderzeichen im Shell-Skript maskieren?

Bash-while-Schleife

Prozesse in einer Sitzung in einer interaktiven Shell oder in einem Skript?

Die While-Schleife in Shell-Skripten

Wie führe ich einen Befehl in einem Shell-Skript aus?

Rückgabewert vom Python-Skript zum Shell-Skript

Warum wird eine Bash-While-Schleife nicht beendet, wenn sie zu einem beendeten Unterbefehl weitergeleitet wird?