Kann mir jemand erklären, warum dies funktioniert (Auflisten des Inhalts eines Verzeichnisses, dessen Name ein Leerzeichen enthält):
ret="$(ls "my dir")"
Sollte es nicht eher so interpretiert werden:
ret="$(ls "
my dir
")"
Wie zum Beispiel bei:
ls "my" "dir"
Und
ls "my dir"
Antwort1
Die beste Vermutung scheint bisher zu sein, dass Sie fragen:
Der Befehl
ret="$(ls "mein Verzeichnis")"ist ein ziemlich schlimmes Beispiel für einen Befehl, der vier Anführungszeichen (
"
) enthält. Man könnte naiverweise erwarten, dass das zweite Anführungszeichen mit dem ersten übereinstimmt und das vierte mit dem dritten, wie hier:ret="$(ls "my dir")" ↑-----↑ ↑-↑
wie es zum Beispiel bei
eat "afternoon snack" dinner "midnight snack"
Stattdessen „funktioniert“ es wie folgt:
ret="$(ls "mein Verzeichnis")" ↑ ↑------↑ ↑ ↑--------------↑Warum werden die verschachtelten Anführungszeichen auf diese Weise analysiert?
Dieser Absatz vonbash(1) könnte es erklären:
Befehlsersetzung
⋮
… Bei Verwendung des Formulars bilden alle Zeichen zwischen den Klammern den Befehl ….$(command)
Ich vermute, das bedeutet, was Sie beobachtet haben, nämlich, dass der Text zwischen „the“ $(
und „the“ )
behandelt wird, als wäre er ein separater Befehl mit eigener Analyse/Paarung von Anführungszeichen, unabhängig von syntaktischen Elementen außerhalb der Klammern. Ich gebe zu, dass es sehr schwer zu interpretieren ist, wenn Sie nicht nach dieser Bedeutung suchen.
Aber Ihre Frage ergibt, so wie sie geschrieben ist, keinen Sinn. Das Ganze hängt von der ganz besonderen Bedeutung $
der Shell ab. Wenn wir das in ein anderes Währungssymbol ändern würden,
ret="£(ls "my dir")"
dann würde es als zwei Wörter behandelt:
ret="£(ls "my
(gefolgt von)
dir")"
denn wenn ein Zeichen, das kein Leerzeichen und kein Sonderzeichen ist, direkt vor einem öffnenden Anführungszeichen oder direkt nach einem schließenden Anführungszeichen steht, wird es in dieselbe Zeichenfolge aufgenommen wie die in den Anführungszeichen eingeschlossenen Zeichen. Beispiel:
cat Wal"*"mart
sucht nach einer Datei namens Wal*mart
, nicht nach einer Datei namens Wal
, einer namens *
und einer namens mart
—
Wal"*"mart
ist gleichwertig mit Wal\*mart
und "Wal*mart"
. Ähnlich verhält es sich mit dem folgenden Beispiel, das vier Wörter zeigt:
eins" "zwei Schnallen" mein "Schuh ist kein" "/Kadett sqrt"(2)" ↑---------↑ ↑--------------↑ ↑--------------------↑ ↑-----------↑
Ich weiß nicht, woher Sie die dreizeilige Aufschlüsselung haben, die Sie in Ihrer Frage gezeigt haben.