Ich hatte erwartet, keine Ausgabe zu bekommen.
Wenn dies nullglob
die Standardeinstellung wäre, würden sich viele Befehle ganz unerwartet verhalten, da es (möglicherweise leider) üblich ist, dass Befehle den Fall von Null- Dateinamen-Argumenten qualitativ anders behandeln als den Fall von einem oder mehreren Dateinamen-Argumenten.
Angenommen, Sie haben aktiviert nullglob
( shopt -s nullglob
) und befinden sich in einem Verzeichnis, in dem keine Dateien übereinstimmen *.txt
. Dann *.txt
wird sich in der Tat zu nichts ausdehnen - kein leeres Feld, aber überhaupt keine Felder - wie Sie es erwartet haben. Aber das hätte folgende Ergebnisse:
ls *.txt
würde alle Dateien im aktuellen Verzeichnis auflisten (außer versteckte Dateien), da dies der ls
Fall ist, wenn Sie keine Dateinamenargumente übergeben.
cat *.txt
würde von der Standardeingabe lesen , denn wenn cat
es keine Dateinamenargumente gibt, ist es, als ob Sie ausgeführt würden cat -
. Wenn es interaktiv ausgeführt wird, wartet es auf Eingaben. Viele Befehle verhalten sich so.
cp *.txt dest/
würde mit dem Fehler scheitern cp: missing destination file operand after 'dest/'
. Dies ist keine Katastrophe, aber es ist verwirrend und ganz anders als der stille Erfolg, der wahrscheinlich erwünscht ist.
file *.txt
und verschiedene andere Programme ohne spezielles Verhalten für den Fall von Argumenten mit dem Dateinamen Null würden immer noch mit einer Fehler- oder Verwendungsmeldung fehlschlagen, wenn keine übergeben werden.
- Selbst Fälle, die sich intuitiv so anfühlen, als sollten sie oft funktionieren, würden dies nicht tun.
printf 'Got file: "%s"\n' *.txt
würde Got file: ""
statt nichts drucken .
- Versehentliches Versäumnis zu zitieren Vorkommen
*
, ?
und [
die sind nicht beabsichtigt , von dem Shell öfter offensichtlich falschen Ergebnisse produzieren würde erweitert werden, aber in einer Weise, um herauszufinden , könnte schwierig sein. Wenn beispielsweise keine Dateinamen im aktuellen Verzeichnis mit beginnen gedit
, wird apt list gedit*
(wo apt list 'gedit*'
beabsichtigt) gerecht apt list
und listet alle verfügbaren Pakete auf.
Es ist also gut, dass Sie dieses Verhalten nicht erhalten, ohne es anzufordern. Die wahrscheinlich häufigste praktische Situation, die tatsächlich durch vereinfacht wird, nullglob
ist for f in *.txt
. Siehe auch diese Frage (mit der Sergiy Kolodyazhnyys Antwort verknüpft ist).
Die schwierigere Frage ist, warum - failglob
wo es ein Erweiterungsfehler ist, einen Glob zu haben, der nicht mit Dateien übereinstimmt - nicht die Standardeinstellung in Bash ist. Ich glaube, Sergiy Kolodyazhnyys Antwort erfasst den Grund dafür, auch ohne ihn direkt anzusprechen. Nicht beibehaltene Globs beizubehalten, ohne einen Expansionsfehler zu erzeugen, ist (möglicherweise leider) das standardisierte Verhalten, und es ist auch traditionelles und daher erwartetes Verhalten. Obwohl bash nicht versucht, vollständig POSIX-kompatibel zu sein, es sei denn, es wird mit dem Namen aufgerufen sh
oder die --posix
Option übergeben, folgen viele seiner Entwurfsoptionen, auch wenn es sich nicht im POSIX-Modus befindet, direkt POSIX. Sie mussten sich für ein Verhalten entscheiden, und es gibt Nachteile, die damit verbunden sind, den Erwartungen der Benutzer zu widersprechen.
Ich denke, dies ist der am wenigsten historisch einflussreiche Aspekt der Angelegenheit, also habe ich ihn zum letzten Mal gespeichert ... aber es ist erwähnenswert, dass nullglob
Verhalten konzeptionell etwas Seltsames ist .
nullglob
erscheint auf den ersten Blick elegant, da syntaktisch der Fall von null übereinstimmenden Dateien nicht anders behandelt wird als der Fall von eins, zwei oder einer anderen Zahl. Die von uns ausgeführten Befehle, für die Globs zu Argumenten erweitert werden , behandeln sie normalerweise nicht gleich, wie oben beschrieben. Aber syntaktisch fühlt sich das zumindest richtig an, was meiner Meinung nach die Motivation für Ihre Frage ist.
Und doch gibt es eine andere, subtilere Inkonsistenz, nullglob
die nicht angesprochen wird - die sie tatsächlich verstärkt. Der Fall von Null-Globbing-Zeichen ("Platzhalter") wird grundlegend anders behandelt als der von einer, zwei oder einer anderen Zahl. Zum Beispiel mit shopt -s nullglob
, wenn ab?d?f
keine Dateien übereinstimmen, wird es entfernt; Wenn ab?d
keine Dateien übereinstimmen, werden sie entfernt. Wenn ab
jedoch keine Dateien übereinstimmen (dh wenn keine Datei vorhanden ist, deren Name genau lautet ab
), wird sie immer noch nicht entfernt. Natürlich wäre es eine Katastrophe, wenn es entfernt würde, da es möglicherweise überhaupt nicht beabsichtigt ist, auf eine vorhandene Datei im aktuellen Verzeichnis zu verweisen. Es verweist möglicherweise nicht einmal auf eine Datei. Damit entfällt jedoch die Hoffnung auf völlige Beständigkeit.
Die drei Verhaltensweisen, die Bash bietet - die Standardeinstellung, Globs, die nicht mit Dateien übereinstimmen, so zu behandeln, als wären sie keine Globs, und sie nicht zu erweitern, das Verhalten, das Sie von ihrer Behandlung erwartet haben (wenn Sie diese seltsame Wendung verzeihen) Dies bedeutet, dass alle Nullen der übereinstimmenden Dateien ( nullglob
) und das sichere Verhalten, sie als Fehler zu betrachten ( failglob
), unterschiedliche Ansätze für die der Shell innewohnende Mehrdeutigkeit darstellen, die nicht wissen kann, ob ein bestimmtes Wort a sein soll Dateiname. Die Shell führt ihre Erweiterungen durch, ohne zu wissen, wie die von ihr aufgerufenen Befehle ihre Argumente behandeln.
Dies ist einer von vielen Fällen der Trennung von Bedenken . In Systemen, deren Design der Unix-Philosophie folgt, soll jedes Teil eines tun und es gut machen . Die Shell verarbeitet Text in Befehle und Argumente und ruft die Befehle auf, von denen die meisten außerhalb der Shell selbst liegen. Dies ist in der Regel viel schöner und vielseitiger als Systeme, bei denen die externen Befehle selbst für die Durchführung dieser Transformationen verantwortlich sind (wie bei den herkömmlichen Befehlsprozessoren unter DOS und Windows). Aber es hat gelegentlich Nachteile.
shopt -s nullglob
werden leere Zeichenfolgen für nicht übereinstimmende Muster undshopt -u nullglob
(Standardeinstellung) das Muster selbst ausgegeben.