Antworten:
Das prüft, dass $1
leer ist, obwohl es in Anführungszeichen gesetzt werden sollte (identisch mit [ -z "$1" ]
). Einige sehr alte Shells haben leere Zeichenfolgen nicht richtig verarbeitet, daher haben Autoren portabler Skripte diesen Überprüfungsstil übernommen. Es war jahrzehntelang nicht notwendig, aber die Leute machen es immer noch so, weil die Leute es immer noch so machen.
[ x$1 = x ]
ist immer noch falsch, [ "x$1" = x ]
wäre aber für shells die ein problem haben wo $1
ist !
oder (
oder -n
.... [ "" = "$1" ]
und case $1 in "")
wäre auch ok.
[ -z "$1" ]
und [ "$1" = "" ]
funktionieren immer noch nicht mit / bin / sh von Solaris 10, dem ersteren mit dash-0.5.4.
[ "$1" = "" ]
funktioniert immer noch nicht mit Solaris /bin/sh
(obwohl Sie es dort verwenden möchten /usr/xpg4/bin/sh
, nicht /bin/sh
). Diesbezüglich wurde Dash im Januar 2009 festgelegt.
Eckige Klammern kennzeichnen einen Test , daher ist [ x$1 = x]
without if
oder ähnliches bedeutungslos, obwohl syntaktisch in Ordnung.
Es soll als wahr gewertet werden, wenn es x$1
erweitert wird x
, und als falsch, wenn es nicht in Anführungszeichen $1
steht (z. B. "hey x"), wird die Shell dies sehen x = x
, sodass diese Konstruktion immer noch nicht sicher ist.
Der Zweck der x = x
Prüfung besteht darin, festzustellen, ob eine Variable leer ist. Eine gebräuchlichere Methode hierfür ist die Verwendung von Anführungszeichen:
if [ "$1" = "" ]; then
Bash Test Betreiber -z
und -n
kann auch verwendet werden, aber sie sind weniger tragbar auf andere Arten von Muscheln. 1
Der Grund für die Anführungszeichen oder das x$1
ist, dass die linke Seite nicht zu nichts erweitert wird, was ein syntaktischer Fehler wäre:
if [ = x ] # No good!
if [ "" = "" ] # Okay.
if [ x = x ] # Also okay.
1. Eigentlich test
kann es ein eigenständiges Dienstprogramm sein, aber die meisten Shells implementieren es als eingebautes. Überprüfen Sie den Unterschied zwischen which test
und type test
. Unter GNU / Linux wird man test
behauptet, auf das eingebaute zu verweisen, aber wenn Sie (z. B.) aufrufen /usr/bin/test
, scheint dieses Dienstprogramm die in der Manpage dokumentierten Funktionen zu implementieren, einschließlich -z
und -n
.
[ x$1 = x ]
wird auch als wahr ausgewertet, wenn dies $1
beispielsweise der Fall ist " -o x"
. Versuchen Sie es sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
. [ x$1 = x ]
ist falsch und macht keinen Sinn.
if
zu benutzen test
, Sie können es vor &&
, ||
nach while
oder untersuchen das Ergebnis mit$?
[ x$1 = x ]
Macht nur Sinn in zsh
. Das vergleicht die Verkettung von x
mit dem ersten Argument des Skripts x
. Der [
Befehl gibt also true zurück, wenn $1
leer oder nicht angegeben.
[ $1 = "" ]
Wäre das nicht funktionieren , weil, in , zsh
wenn eine leeren Variable wird nicht in der Liste Kontext zitiert, es überhaupt statt einem leeren Argument ohne Argument erweitert, so dass , wenn $1
waren nicht gesetzt oder leer, das [
würde Befehl nur als Argument erhalten [
, =
die leeren Zeichenfolge und ]
woraus es keinen Sinn machen konnte. [ -z "$1" ]
oder [ "$1" = "" ]
wäre aber OK wie in POSIX-Shells.
In Bourne-ähnlichen / POSIX-Shells [ x$1 = x ]
macht das keinen Sinn. Das ist der split + glob-Operator, der irgendwie auf die Verkettung x
und das erste Argument des Skripts angewendet wird, in der Hoffnung, dass das Ergebnis und =
und x
und ]
einen gültigen Testausdruck für den [
Befehl bilden.
Zum Beispiel, wenn das Skript eine übergeben wurde " = x -o x ="
Argument, [
würde diese Argumente erhalten: [
, x
, =
, x
, -o
, x
, =
, x
, ]
, die [
als Vergleich würden verstehen , x
mit x
und x
mit x
und true zurück.
Wenn $1
waren "* *"
, dann wäre die Schale an denen passiert [
die Liste der Dateien im aktuellen Verzeichnis , dessen Namen beginnt mit dem Befehl x
(Glob Erweiterung der x*
), dann ist die Liste der nicht versteckten Dateien (Erweiterung *
) ... , die [
unwahrscheinlich ist in der Lage sein , irgendeinen Sinn machen aus. Die einzigen Fälle, in denen dies sinnvoll wäre, sind Fälle, in denen $1
keine Platzhalter oder Leerzeichen enthalten sind.
Was Sie jetzt manchmal finden, ist Code wie:
[ "x$1" = x ]
Dies wird verwendet, um zu testen, ob $1
leer oder nicht gesetzt ist.
Der normale Weg, auf eine leere oder nicht gesetzte Variable zu testen, ist:
[ -z "$1" ]
Aber das nicht für einige Werte von $1
wie =
in einigen (nicht-POSIX) [
Implementierungen wie das Builtin man in dem Bourne - Shell wie gefunden /bin/sh
auf Solaris 10 und vor oder einigen alten Versionen dash
(bis 0.5.4) oder den sh
von einigen BSDs.
Das liegt daran [
sieht [
, -z
, =
, ]
und beschwert sich über Argumente des fehlenden =
Binäroperators statt es zu verstehen , wie der -z
unäre Operator auf die angelegte =
Zeichenfolge.
Ebenso [ "$1" = "" ]
scheitert bei einigen Implementierungen an [
if $1
is !
oder (
.
In diesen Shell / [
Implementierungen:
[ "x$1" = x ]
ist immer ein gültiger Test, unabhängig vom Wert von $1
.
[ "" = "$1" ]
und:
[ -z "${1:+x}" ]
und
case $1 in "") ...; esac
Wenn Sie sicherstellen möchten, dass kein Argument angegeben wird, gehen Sie wie folgt vor:
[ "$#" -eq 0 ]
Das heißt, Sie überprüfen die Anzahl der an das Skript übergebenen Argumente.
Beachten Sie, dass heute [ -z "$var" ]
deutlich von POSIX spezifiziert und kann nicht umhin , in konformen [
Implementierungen (und bash
‚s [
ist und seit Jahrzehnten). Sie sollten sich also in POSIX sh oder bash
Skripten darauf verlassen können.
x$1
verkettet zwei Zeichenketten x
und $1
wenn $ 1 leer ist, ist x $ 1 gleich x, und [x $ 1 = x] ist als Ergebnis wahr. x = y
wird zum Vergleichen der Zeichenfolge in sh verwendet
x$1
wird nicht in Anführungszeichen gesetzt, daher wird das Teilen und Verschieben dieser Elemente ausgeführt.
[ x$1 = x ]
ist wahr, wenn $1
nicht gesetzt / null / leer ist oder nicht.
Versuchen Sie sich mit:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
und
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"
[ x$1 = x ]
Dies gilt auch, wenn dies $1
beispielsweise der Fall ist " -o x"
. Versuchen Sie es sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
. [ x$1 = x ]
ist falsch und macht keinen Sinn.