Aus Neugier ist es bei einem Bash-Variablen-Vergleich (dessen Wert ist ein integer
) möglich, ihn mit einem vordefinierten Wert zu testen, der entweder als int
oder als deklariert ist string
.
Beispielskript :
#!/bin/bash
f1()
{
[ "$1" == "1" ] && echo "$FUNCNAME: \"1\" compared as string"
}
f2()
{
[[ "$1" -eq 1 ]] && echo "$FUNCNAME: \"1\" compared as int"
}
f1 $1
f2 $1
Ausgabe :
$ ./param.sh 1
f1: "1" compared as string
f2: "1" compared as int
und
$ ./param.sh blah
$
Beide Funktionen verhalten sich gleich, und ich frage mich, ob es beim Überprüfen einer Ganzzahlvariablen einen bevorzugten Weg gibt. Ich würde für die Überprüfung gehen im int
Vergleich zu, int
wie es ist strenger , aber ich frage mich , ob es irgendwelche ziehen Rücken tun es mit string
?
In diesem Fall geht f2()
es auch strenger um den Vergleich, dh das Übergeben eines Dezimalwertes unterbricht diesen, wohingegen f1()
es kein Problem darstellt.
Antworten:
Ja, viele Unterschiede. Zum Beispiel
=
prüft , ob exakte Zeichenfolge Gleichheit, sondern-eq
wertet arithmetisch beide Ausdrücke , bevor für die Gleichstellung Überprüfung:Außerdem ist die leere Zeichenfolge numerisch gleich Null:
Und eine ganze andere Klasse von Unterschieden tritt auf, wenn Sie die Vergleichsoperatoren einbeziehen - unter Berücksichtigung von
<
vs-lt
, zum Beispiel:Dies liegt daran, dass die Zeichenfolge "2" alphabetisch nach der Zeichenfolge "10" steht (da 1 vor 2 steht), die Zahl "2" jedoch numerisch kleiner als die Zahl "10" ist.
quelle
(( ... ))
numerische Operationen gibt.(( " 1 " == 1 )) && echo yes || echo no
Ergebnisse inyes
Der Vergleich zwischen Ganzzahl und Zeichenfolge wird am wichtigsten, wenn Sie einen Vergleich durchführen, der größer oder kleiner ist als:
Das erste scheitert, weil 9 nach 11 kommt, wenn es lexikographisch sortiert ist.
Beachten Sie, dass die Verwendung von Anführungszeichen nicht bestimmt, ob Sie Zeichenfolgen oder Zahlen vergleichen, sondern der Operator. Sie können die obigen Anführungszeichen hinzufügen oder entfernen, es macht keinen Unterschied. Bash fängt undefinierte Variablen in doppelten Klammern ab, sodass keine Anführungszeichen erforderlich sind. Die Verwendung von Anführungszeichen mit einzelnen Klammern für numerische Tests wird Sie nicht retten, da:
ist sowieso ein Fehler ("Integer-Ausdruck erforderlich"). Anführungszeichen sind ein wirksamer Schutz bei Zeichenfolgenvergleichen in einzelnen Klammern:
Hinweis innerhalb doppelten Klammern,
""
werden-eq 0
aber nicht== 0
.quelle
[[
merkt sich, wo sich die Variablen befinden, und lässt sich nicht von leeren Variablen täuschen. Einzelne Klammern ([
) haben diese Funktion nicht und erfordern Anführungszeichen.[[ -lt 11 ]]
ist ein Fehler, ist es abernothing=; [[ $nothing -lt 11 ]]
nicht. Ich habe den letzten Absatz ein wenig überarbeitet.Zusätzlich zu dem, was gesagt wurde.
Das Vergleichen auf Gleichheit ist mit Zahlen schneller, obwohl Sie in Shell-Skripten selten eine schnelle Berechnung benötigen.
quelle
=
, da die Verwendung-eq
auch für "+123" passen würde. Wenn Sie wissen möchten, dass "Ist diese Variable, wenn sie als arithmetischer Ausdruck ausgewertet wird, gleich 123", können Sie nur verwenden-eq
. Das einzige Mal, dass ich sehen kann, wo es einem Programmierer egal ist, welche Definition von Gleichheit verwendet wurde, ist, wenn er weiß, dass der Inhalt der Variablen im Voraus auf ein bestimmtes Muster beschränkt ist.b=234
) passt zu diesem Muster - Sie wissen, dass es nicht +234 oder "234" oder "233 + 1" ist, da Sie es selbst zugewiesen haben, sodass Sie wissen, dass der Vergleich als Zeichenfolge und als Zahl gleichermaßen gültig ist. Aber das Skript des OP, da es Eingang als Befehlszeilenargument nimmt, nicht über diese Einschränkung - zu prüfen , nennt es als./param.sh 0+1
oder./param.sh " 1"