@track: Das dachte ich auch zuerst. Dein Fall ließe sich also etwas weniger kryptisch auf das hier reduzieren:
$ echo a{1,3}{1,3}b
a11b a13b a31b a33b
Damit bin ich einverstanden.
Das Problem ist nur, dass du in diesem Fall keine Befehlssubstitution hast, wodurch die Quotes anders ausgewertet werden. Die Quotes hier um das äußere $(...)
bilden ein Paar, ebenso die Quotes innen um die geschwiffenen Klammern herum:
| echo "$(echo "{1,3}{1,3}")"
|
Das sieht auch die BashFAQ so (letzter Punkt dort). Und so, wie ich das bisher immer verstanden habe, heißt der Befehl:
Befehlssubstitution. Führe in einer Subshell „echo "{1,3}{1,3}"
“ aus. Durch die Quotes hier müsste dabei eigenltich der String „{1,3}{1,3}
“ herauskommen.
Die Befehlssubstitution fängt die Ausgabe ihrer Subshell auf.
Da um die Substitution selbst herum noch einmal Quotes stehen, wird weitere Expansion unterbunden. Der String „{1,3}{1,3}
“ sollte also auch vom äußeren „echo
“ exakt übernommen werden.
Dass die inneren Quotes ausreichend schützen sollten, sieht man auch an diesen Beispielen:
$ echo "$(echo "*")" # kein Globbing
*
$ echo "$(echo *)" # hier hingegen schon
datei1 datei2 foo bar baz
$ echo "d$(echo *)" # hier sieht man: Globbing passiert in der Subshell,
ddatei1 datei2 foo bar baz # sonst dürften nur datei1 und datei2 erscheinen,
# wie man am nächsten Beispiel sehen kann.
$ echo d$(echo "*")
datei1 datei2
Schaltet man mal „set -x
“ an, dann sieht man beim ersten Beispiel mit dem Sternchen, dass genau das passiert, was ich erwartet hatte:
$ echo "$(echo "*")"
++ echo '*'
+ echo '*'
*
Bei dem Fehlerfall mit der Brace-Expansion aber:
$ echo "$(echo "{1,3}{1,3}")"
++ echo 11
++ echo 13
++ echo 31
++ echo 33
+ echo 11 13 31 33
11 13 31 33
Huh? Wieso wird denn das „echo
“ innen mehrfach gestartet? Bei der einfachen Variante ohne Quotes und Subshell, wenn die Expansion korrekterweise durchgeführt wird, sieht doch so aus:
$ echo {1,3}{1,3}
+ echo 11 13 31 33
11 13 31 33
Da gibt es „echo
“ nicht mehrfach.
Okay, gut, seine Frage ist geklärt. Ich würde dem aber wirklich gerne auf den Grund gehen – das ist ein Rätsel! 😉 Bei Bedarf möge bitte ein Mod abtrennen oder so.
Zu deinem Edit:
$ echo $(echo "{1,3}{1,3}")
{1,3}{1,3}
Das Ergebnis kann ich bestätigen. Aber es ist mir echt ein Rätsel. Das widerspricht einfach dem Eintrag da oben in der BashFAQ, meiner Intuition 😉 und auch der Tatsache, dass hier Globbing passiert:
$ echo $(echo "*")
bar baz datei1 datei2 foo
Würden die Quotes richtig schützen, gäbe es kein Globbing. Und einfach mal angenommen, dass Globbing und Brace-Expansion nicht vergleichbar seien – wie bekomme ich es dann im folgenden Beispiel hin, dass die Leerzeichen nicht verloren gehen?
$ echo $(echo "a {1,3}{1,3} b")
a {1,3}{1,3} b
Lässt du hier die Befehlssubstitution weg, sind die Leerzeichen noch, das heißt im Umkehrschluss, dass sie erst durch das Weiterverarbeiten der Ausgabe der Subshell verloren gehen. Sprich, ich müsste das durch Setzen von Quotes um die $(...)
herum verhindern können. Dann gibt es aber wieder unser Problem:
$ echo "$(echo "a {1,3}{1,3} b")"
a 11 b a 13 b a 31 b a 33 b
Auch das hier ist mal seltsam:
$ echo "$(echo \"a {1,3}{1,3} b\")"
"a 11 13 31 33 b"
Wäre es so, wie du sagst, sollten dann nicht die Backslashes die Quotes hier von ihrer Wirkung entbinden?
Irgendwo habe ich einen kapitalen Denkfehler drin. Oder das ist ein Bug in der Bash. ☺