"Test -n && Echo nicht leer" gibt "nicht leer" aus. Ist das erwartetes Verhalten?

7

Wenn ich die folgende Zeile ausführe

test -n && echo not empty

es wird "nicht leer" gedruckt. Dies tritt auf, wenn Sie eine leere Variable haben und auf Nicht-Leere testen, während Sie vergessen, den Wert anzugeben:

VAR=
test -n  $VAR  && echo wrong 1
test -n "$VAR" && echo wrong 2

Ist das erwartetes Verhalten?

Daniel Kullmann
quelle

Antworten:

9

Ja, dies ist das erwartete Verhalten. Wenn nur ein Argument übergeben wird, testwird eine Längenprüfung durchgeführt. Von man bash:

teste und [bewerte bedingte Ausdrücke anhand eines Regelsatzes, der auf der Anzahl der Argumente basiert.

0 Argumente: Der Ausdruck ist falsch.

1 Argument: Der Ausdruck ist genau dann wahr, wenn das Argument nicht null ist.

Das heißt, im Wesentlichen ist es das Äquivalent von test foo, wird aber -nals Zeichenfolge verwendet.

Chris Down
quelle
3

test -nist auf den ersten Blick missgebildet, da -nein Argument erforderlich ist. Ich glaube, einige historische Implementierungen haben es als Syntaxfehler behandelt (und einen Status ungleich Null zurückgegeben). In allen Muscheln, denen Sie im 21. Jahrhundert wahrscheinlich begegnen werden, ist das Verhalten jedoch genau definiert (von POSIX gemäß der bestehenden Praxis): Wenn testnur ein Argument vorhanden ist, ist es genau dann wahr, wenn dieses Argument nicht vorliegt -leeren.

Beachten Sie, dass der Test für einige nicht leere Werte von möglicherweise falsch ist, wenn Sie die Anführungszeichen weglassen $VAR. Es kann sogar eine Fehlermeldung ausdrucken, wenn sich Globbing-Zeichen befinden $VAR.

VAR='foo -a -z bar'; test -n $VAR || echo "true... and false is false"
VAR='= n-'; test -n $VAR || echo "this is an equality test"
VAR='*'; test -n $VAR || echo "you may or may not see this depending on what files are in the current directory"

test -z $VAR ist ähnlich kaputt.

Ksh, bash und zsh haben ein [[ … ]]bedingtes Konstrukt, das das Traditionelle testund die [Dienstprogramme imitiert . Im Gegensatz dazu [ist dies entweder ein externes Dienstprogramm oder ein integriertes Dienstprogramm, das wie eines analysiert [[ … ]]wird, Teil der Shell-Syntax. Es gibt kein Wort, das sich im Inneren teilt oder klirrt [[ … ]]. [[ -n $VAR ]]ist in Ordnung (solange es Ihnen egal ist, dass Ihre Skripte nicht unter anderen Shells wie Asche ausgeführt werden).

Gilles 'SO - hör auf böse zu sein'
quelle
1

Überprüfen Sie auch [[ ... ]], welches Verhalten nicht auftritt:

[[ -n $VAR ]] && echo wrong 3
[[ -n "$VAR" ]] && echo wrong 4
Choroba
quelle
Interessant und es wert, sich dessen bewusst zu sein, aber "leiden" ist hier wahrscheinlich nicht das richtige Wort ... [[ ... ]]ist nicht dasselbe, [ ... ]das das gleiche Verhalten zeigt wie testund die Funktion, auf die in man bash... Bezug genommen wird . Innerhalb von [[ ... ]]Variablen muss es nicht sein "$ quote", um als Variable erkannt zu werden (dh als Argument für [[) ... Dies läuft auf einen einfachen Fall hinaus: Die Variable wurde nicht in Anführungszeichen gesetzt und sollte es auch gewesen sein.
Peter.O
0

Da die Bash aufgebaut testist und /usr/bin/testzum gleichen Ergebnis führt, sage ich ja, es ist erwartetes Verhalten.

Benutzer unbekannt
quelle
0

Es scheint, wenn Sie Folgendes tun:

VAR=
test -n $VAR && echo helloworld

Es behandelt es so, als ob das Argument nicht da wäre:

test -n && echo helloworld

Und wenn das Argument nicht angegeben wird, führt es aus irgendeinem Grund den Befehl immer danach aus (dh es zeigt helloworld an). Ich habe dies bei einem anderen unuären Operator versucht und es hat dasselbe getan:

FILENAME=
test -f $FILENAME && echo helloworld

Ich denke, wenn Sie erwartetes Verhalten haben wollen, müssen Sie das Argument zitieren:

VAR=
test -n "$VAR" && echo helloworld
FILE=
test -f "$FILE" && echo helloworld

Das Obige ergibt keine Meldung, die auf dem Bildschirm wiedergegeben wird.

Was ist das erwartete Verhalten? Ich kann es nirgendwo in der Dokumentation finden, aber es scheint ziemlich reproduzierbar und konsistent zu sein.

Stephen Quan
quelle