Angenommen, ich habe ein Skript:
some-command "$var1" "$var2" ...
Und für den Fall, dass var1
es leer ist, würde ich es vorziehen, es durch nichts anstelle der leeren Zeichenfolge zu ersetzen, so dass der ausgeführte Befehl lautet:
some-command "$var2" ...
und nicht:
some-command '' "$var2" ...
Gibt es einen einfacheren Weg, als die Variable zu testen und bedingt einzuschließen?
if [ -n "$1" ]; then
some-command "$var1" "$var2" ...
# or some variant using arrays to build the command
# args+=("$var1")
else
some-command "$var2" ...
fi
Gibt es eine Parametersubstitution, die in bash, zsh oder dergleichen zu nichts erweitert werden kann? Möglicherweise möchte ich in den restlichen Argumenten immer noch Globbing verwenden. Das Deaktivieren und Aufheben der Anführungszeichen für die Variable ist daher keine Option.
bash
shell-script
zsh
variable
muru
quelle
quelle
man
Seite nicht gelesen? (-;Antworten:
Posix-konforme Shells und Bash haben
${parameter:+word}
:Sie können also einfach Folgendes tun:
und müssen
var1
überprüft und verwendet"$var1"
werden, wenn sie gesetzt und nicht leer sind (mit den üblichen Regeln für doppelte Anführungszeichen). Sonst dehnt es sich zu nichts aus. Beachten Sie, dass hier nur der innere Teil und nicht das Ganze zitiert wird.Das gleiche funktioniert auch in zsh. Sie müssen die Variable wiederholen, es ist also nicht ideal, aber es funktioniert genau so, wie Sie es wollten.
Wenn Sie möchten, dass eine Variable mit festem aber leerem Inhalt zu einem leeren Argument erweitert wird, verwenden Sie
${var1+"$var1"}
stattdessen.quelle
word
Teil.:+
und zu ändern+
.sh
/dash
für potenzielle Chokepoint-Skripte zu verwenden, daher schätze ich es immer, wenn jemand zeigt, wie etwas möglich ist, ohne auf Bash zurückzugreifen.Dies
zsh
geschieht standardmäßig, wenn Sie die Anführungszeichen weglassen:Eigentlich ist der einzige Grund , warum Sie noch brauchen Anführungszeichen in zsh um Parameter Expansion ist dieses Verhalten zu vermeiden (die leere Entfernung) als
zsh
nicht über die anderen Probleme , die anderen Schalen beeinflussen , wenn Sie keine Parameter Erweiterungen zitieren (die impliziten Split + glob) .Sie können dasselbe mit anderen POSIX-ähnlichen Shells tun, wenn Sie split und glob deaktivieren:
Nun würde ich argumentieren, dass wenn Ihre Variable entweder 0 oder 1 Wert haben kann, es ein Array und keine skalare Variable sein sollte und verwenden Sie:
Verwenden Sie,
var1=(value)
wennvar1
ein Wert enthalten sein soll,var1=('')
wenn ein leerer Wert enthalten sein soll undvar1=()
wenn kein Wert enthalten sein soll.quelle
Ich bin mit rsync in einem Bash-Skript darauf gestoßen, das den Befehl mit oder ohne
-n
Umschalten zwischen Testläufen gestartet hat . Es stellt sich heraus, dass rsync und eine Reihe von Gnu-Befehlen ausgeführt werden''
als gültiges erstes Argument gelten und sich anders als wenn sie nicht vorhanden wären.Das Debuggen dauerte eine Weile, da Null-Parameter fast unsichtbar sind.
Jemand auf der rsync-Liste zeigte mir, wie ich dieses Problem vermeiden und gleichzeitig meine Codierung erheblich vereinfachen kann. Wenn ich es richtig verstehe, ist dies eine Variation des letzten Vorschlags von @ Stéphane Chazelas.
Erstellen Sie Ihre Befehlsargumente in mehreren separaten Variablen. Diese können in einer beliebigen Reihenfolge oder Logik festgelegt werden, die dem Problem entspricht.
Verwenden Sie dann am Ende die Variablen, um ein Array zu erstellen, in dem sich alles an der richtigen Stelle befindet, und verwenden Sie dies als Argumente für den tatsächlichen Befehl.
Auf diese Weise wird der Befehl nur an einer Stelle im Code ausgegeben, anstatt für jede Variation der Argumente wiederholt zu werden.
Jede leere Variable verschwindet mit dieser Methode.
Ich weiß, dass das Verwenden von eval sehr verpönt ist. Ich erinnere mich nicht an alle Details, aber es schien notwendig zu sein, damit die Dinge auf diese Weise funktionieren - etwas, das mit dem Umgang mit Parametern mit eingebettetem Leerraum zu tun hat.
Beispiel:
quelle