Ich bekomme, was ich erwartet habe, wenn ich das mache in bash
:
[ "a" == "a" ] && echo yes
Es gab mir yes
.
Aber wenn ich das mache zsh
, bekomme ich folgendes:
zsh: = not found
Warum verhält sich derselbe Befehl ( /usr/bin/[
) in verschiedenen Shells unterschiedlich?
$PATH
durchsucht wurde. und==
ist keine gültigetest
Syntax für den/usr/bin/[
Weg. Ist einfach=
in Ordnung.Antworten:
Es ist nicht
/usr/bin/[
in einer der Muscheln. In Bash, verwenden Sie den eingebauten intest
/[
Befehl , und in ähnlicher Weise in zsh .Der Unterschied besteht darin, dass zsh auch eine
=
Erweiterung hat : Erweitert=foo
den Pfad zurfoo
ausführbaren Datei. Das bedeutet, dass==
versucht wird, einen Befehl zu finden, der=
in Ihrem aufgerufen wirdPATH
. Da dieser Befehl nicht vorhanden ist, wird der Fehler angezeigtdass Sie gesehen haben (und in der Tat würde das gleiche passieren, selbst wenn Sie tatsächlich verwenden
/usr/bin/[
).Sie können verwenden
==
hier , wenn Sie wirklich wollen. Dies funktioniert wie in zsh erwartet:weil das Zitat verhindert, dass die
=word
Erweiterung ausgeführt wird. Sie können dieequals
Option auch mit deaktivierensetopt noequals
.Sie wären jedoch auch besser dran:
=
den POSIX-kompatiblen Gleichheitstest ; oder[[
Bedingungen mit==
sowohl in Bash als auch in zsh zu verwenden . Im Allgemeinen[[
ist es einfach besser und sicherer, einschließlich der Vermeidung dieser Art von Problemen (und anderer) durch spezielle Parsing-Regeln.quelle
[
und[[
? (Die Suche bei Google nach[ vs [[
gibt mir nur Ergebnisse fürvs
LOL)[[
unterstützt in beiden Fällen eine größere Auswahl an Tests und verfügt über benutzerdefinierte Analyseregeln, die das Zitieren von Variablen, Operatoren usw. vermeiden. Wenn Sie speziell entweder Bash oder zsh verwenden, verwenden Sie[[
. Wenn Sie ein portables Skript schreiben, schreiben Sie in den POSIX-kompatiblen Befehl[
/test
(der auf Ihrem laufenden System möglicherweise ein echter Befehl ist oder nicht).[[
dort verwenden und vergessen[
existiert.[[
ist anders fähig. versuchen Sie dies damit :for f in *; do [ -e "$f" ] && for a in f d h p S b c; do [ "-$a" "$f" ] && for p in r w x u g; do [ "-$p" "$f" ] || p=-; a=$a$p; done && break; done && printf "%s:\t%s\n" "$a" "$f"; done
.=
/==
ist wohl ein Fall , in dem[[
besser ist , nicht als[
, wie[[ a == b ]]
ist tut „a“ entsprechen die „b“ Muster und nicht „a“ ist gleich „b“ , wie man erwarten würde. Das heißt, Sie müssen zum Beispiel schreiben[[ $a == "$b" ]]
.[
Wenn Sie mit dem Befehl wissen, wie das Parsen von[ "$a" = "$b" ]
Befehlen funktioniert, müssen Sie ihn zumindest schreiben , um den Operator split + glob wie in anderen Befehlen zu verhindern. In diesem Sinne und wenn Sie -a oder -o nicht verwenden,[
ist dies in POSIX-konformen Implementierungen sicher.Und zsh und bash geben die gleiche Antwort (
type
ist auch für beide Shells eingebaut):quelle
[
ist ein Shell-Befehl in bash und in zsh:Aus der Dokumentation zu Shell Builtin Commands :
Die offizielle Dokumentation (
$ help test
) erlaubt nur die Verwendung von=
:Der richtige Ausdruck wäre also:
Was passiert ist, dass Bash etwas weniger streng ist. Die Unterstützung des
==
Bedieners mit[
scheint eine Bash-Erweiterung zu sein, und es wird nicht empfohlen, sie zu verwenden:Wenn Sie verwenden möchten
==
, sollten Sie das[[
Schlüsselwort verwenden:Beachten Sie, dass dies
[[
weniger portabel ist (nicht POSIX). Aber sowohl bash als auch zsh unterstützen es.quelle
In beiden Shells
bash
undzsh
ist das[
Dienstprogramm eine integrierte Shell. Dies ist die Shells-Implementierung dieses Tools, die der Binärdatei vorgezogen wird/usr/bin/[
. Die unterschiedlichen Ergebnisse werden durch unterschiedliche Implementierungen verursacht.In akzeptiert
bash
das[
DienstprogrammCONDITIONAL EXPRESSIONS
als[[
zusammengesetzten Befehl. Laut Bashs Manpage sind beide=
und==
gültig:In
zsh
versucht das[
Dienstprogramm, POSIX und seine Erweiterungen dort zu implementieren, wo diese angegeben sind. In der Spezifikation des POSIX-Testdienstprogramms ist kein==
Operator definiert.quelle