Ich bin mir bei dem Vergleich, den ich durchführe, nicht sicher:
if [ "$exit_status" -eq 0 ];then
#some statements
fi
Ist dies die richtige Methode zum Vergleichen von Zahlen oder Anführungszeichen, bei der die Variable exit_status
zu einer Zeichenfolge wird, die mit 0 verglichen wird? Ich weiß nicht, ob dies in manchen Szenarien fehlschlagen könnte.
Antwort1
Ja, das ist richtig.
Anführungszeichen in Shells dienen anderen Zwecken als in anderen Sprachen. Siehediese Antwortfür mehr Details.
In der Shell werden Anführungszeichen verwendet, um zu verhindern, dass die Shell bestimmte Zeichen speziell behandelt, und um bestimmte Vorgänge zu verhindern, die die Shell andernfalls bei bestimmten Erweiterungstypen ausführen würde (wie in diesem Fall der Variablenerweiterung).
Normalerweise möchten Sie in diesem Fall, dass "$exit_status"
der Befehl auf ein Argument erweitert wird [
, das den Inhalt dieser Variable darstellt, also benötigen Sie die Anführungszeichen.
Antwort2
[ "$exit_status" -eq 0 ]
ist korrekt, wenn $exit_status nur Ziffern enthält, und Sie könnten die Anführungszeichen genauso gut entfernen (solange IFS keine Ziffern enthält).
Wenn x leer oder nicht gesetzt ist, [ "$x" -eq 6 ]
tritt ein Fehler auf, aber Folgendes [[ "$x" -eq 6 ]]
passiert nicht:
$ x=; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ unset x; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ x=; [[ "$x" -eq 6 ]]
$ unset x; [[ "$x" -eq 6 ]]
$
Arithmetische Operatoren entfernen Leerzeichen:
$ [ '6 ' -eq $'\n\t6' ]; echo $?
0
Innerhalb von [[ sind die Operanden der arithmetischen Operatoren arithmetische Ausdrücke, so ist beispielsweise [[ 4 -eq 2+2 ]]
wahr. Zahlen, die mit 0 beginnen, werden als Oktalzahlen behandelt:
$ [[ 010 -eq 8 ]]; echo $?
0
$ [ 010 -eq 8 ]; echo $?
1
Ich verwende häufig = / ==, sogar zum Vergleichen von Ganzzahlen. = und == sind in Bash sowohl innerhalb von [[ als auch innerhalb von [ gleichwertig. == und [[ sind von POSIX nicht definiert.
Worttrennung und Pfadnamenerweiterung werden innerhalb von [[ nicht durchgeführt. [[ $x = $y ]]
behandelt y als Muster, [[ $x = "$y" ]]
behandelt y jedoch wörtlich:
$ x=44; y='4*'
$ [[ $x = $y ]]; echo $?
0
$ [[ $x = "$y" ]]; echo $?
1
Antwort3
Das Anführen von Zahlen ist allerdings wenig hilfreich. Wenn der Parameterwert eine Zahl ist, ändern die Anführungszeichen nichts, und wenn nicht, schlägt das if trotzdem fehl. OK, nicht in jedem Fall:
exit_status="a = a -o 0"; [ "$exit_status" -eq 0 ] # returns false
exit_status="a = a -o 0"; [ $exit_status -eq 0 ] # returns true
Dies liegt daran, dass [
es sich zwar um ein integriertes Bash-Befehlselement handelt, es sich aber dennoch um einen einfachen Befehl handelt, während es [[
sich um einen zusammengesetzten Befehl handelt, der die Befehlszeilenanalyse ändert.