Anweisungsblöcke Mechanismus in Shell-Skripten?

7

In Beginning Linux Programming book. Es gibt einen Abschnitt über den Anweisungsblock . In diesem Teil sieht die Erklärung wie folgt aus.

Anweisungsblöcke

Wenn Sie mehrere Anweisungen an einer Stelle verwenden möchten, an der nur eine zulässig ist, z. B. in einer UND- oder ODER-Liste, können Sie dies tun, indem Sie sie in geschweifte Klammern {} setzen, um einen Anweisungsblock zu erstellen. Siehe zum Beispiel den folgenden Code:

get_confirm && {
    grep v "$cdcatnum" $tracks_file > $temp_file 
    cat $temp_file > $tracks_file
    echo
    add_record_tracks
}

Bitte erläutern Sie, wie der Code im Anweisungsblock ausgeführt wird ...

Alamin
quelle
Der Code in den geschweiften Klammern wird so ausgeführt, als ob es keine geschweiften Klammern gäbe.
Hauke ​​Laging

Antworten:

11

Der darin enthaltene Code wird { ... }genau so ausgeführt, wie er ohne die geschweiften Klammern ausgeführt worden wäre, außer dass er jetzt vom Exit-Status von abhängt get_confirm.

Wenn get_confirmExits mit einem Exit-Status von Null ("Erfolg") beendet werden, wird der Block ausgeführt, andernfalls nicht.

Es ist gleichbedeutend mit

if get_confirm; then
    # the contents of the block goes here
fi

(was ich denke sieht schöner aus)

Das Beispiel des Buches ist meiner Meinung nach kein gutes Beispiel für eine häufige Verwendung von { ... }. Ein besseres Beispiel wäre gewesen

{ echo 'hello world'; date; } >file

Dabei wird eine einzige Umleitung verwendet, um die Standardausgabe beider Befehle im { ... }Block in dieselbe Datei umzuleiten .

Dies ist ähnlich (und hat in diesem Fall den gleichen Effekt wie)

( echo 'hello world'; date ) >file

Die Anweisungen in werden jedoch { ... }in derselben Umgebung wie die Shell ausgeführt, während die Anweisungen in ( ... )in einer Subshell (einer separaten Umgebung) ausgeführt werden.

Sie können den Unterschied mit sehen

{ a=42; }; echo $a

und

( a=1973 ); echo $a

Der erste wird ausgegeben, 42während der zweite nicht ausgegeben wird 1973(die Zuweisung erfolgt in einer Unterschale und kann die Umgebung außerhalb nicht beeinflussen).

Hinweis zur Grammatik: Das Schließen }eines { ... }Blocks muss nach einer neuen Zeile oder a erfolgen ;. { echo 'hello' }ist nicht gültig, während beide { echo 'hello'; }und

{ 
    echo 'hello'
}

sind.

Kusalananda
quelle
immer @Kusalananda auf Rettung ..
Alamin
@Kusalananda, tut mir leid, wenn es offtopisch ist, aber ist diese {}Syntax - Bash-spezifisch oder POSIX-konform?
Dan M.
@ DanM. Die { ...; }Syntax lautet POSIX. Es erstellt einen zusammengesetzten Befehl aus den Befehlen, die es kapselt, so dass "es als ein einziger Befehl fungiert" in Bezug auf Umleitungen usw.
Kusalananda
@Kusalananda danke. Ich werde andere Ursachen untersuchen, die möglicherweise erklären, warum mein Skript eine leere Ausgabe unter Bindestrich hat, aber nicht zsh und bash.
Dan M.
@ DanM. Sie könnten eine Frage dazu stellen.
Kusalananda