Hallo!
Ich dachte, ich könne mit einer Commandsubstitution (i.f. CS) eine Zuweisung aus einer Datei schneiden - hier ein Demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 | t530:~/proj/mini/forum 🐧> echo "net=77.77.77 > echo foobar" > test.rc t530:~/proj/mini/forum 🐧> cat test.rc net=77.77.77 echo foobar t530:~/proj/mini/forum 🐧> head -1 test.rc net=77.77.77 t530:~/proj/mini/forum 🐧> $(head -1 test.rc) net=77.77.77: Befehl nicht gefunden. t530:~/proj/mini/forum 🐧> tail -1 test.rc echo foobar t530:~/proj/mini/forum 🐧> $(tail -1 test.rc) foobar |
Wie man sieht: Das echo-Kommando wird klaglos ausgeführt, die Zuweisung nicht (Befehl nicht gefunden).
Kann jmd. erklären, wieso die Zuweisung einen Fehler provoziert?
Ach - wie so oft, wenn man den Fehler oder das Problem en detail zu erklären versucht, kommt man selbst drauf.
Hier aber auch nur fast.
Auszug aus der Bashmanpage, Abschnitt CS
1 2 | Command Substitution Command substitution allows the output of a command to replace the command name. (...) |
Soweit, so schön. Der Output von head -1 test.rc
ist net=77.77.77
. Noch sind wir im grünen Bereich.
1 2 | Bash performs the expansion by executing command in a subshell environment and replacing the command substi- tution with the standard output of the command, with any trailing newlines deleted. (...) |
"Subshell environment" läutet eine Alarmglocke, aber das Subshell-Env. ersetzt den Befehl head -1 test.rc
mit "net=77.77.77" - problematisch wäre, wenn der Befehl "net=77.77.77" in einer Subshell liefe, weil er dann für die aufrufende Shell ohne Wirkung bliebe. Aber hier ist der Output ja, wie bei dem Gegenbeispiel mit "echo", wie man sieht, natürlich sichtbar; das ist ja der Witz an CS.
Also die Anweisung "echo foobar" wird, wie erwartet ausgeführt, aber "net=77..." nicht, obwohl es doch beides Anweisungen sind.
Kann das jmd. erklären?
Rationale: Man ergänzt ja oft die .bashrc um neue Funktionen, Aliase und Shellvariablen. Ich habe dann immer Skrupel die .bashrc neu zu sourcen, weil vielleicht steht da ja irgendwo etwas wie "PATH=$PATH:~/bin", und wenn das 10x aufgerufen wird, dann hat man ":~/bin:~/bin:~/bin:~/bin:~/bin:~/bin:~/bin:~/bin:~/bin" (nicht nachgezählt) im Pfad stehen, was nicht schön ist, auch nicht wirklich problematisch, aber wenn das jmd. sieht wird es doch ein Hochziehen der Augenbrauen beim Betrachter womöglich triggern.
Workaround:
Workarounds interessieren mich nicht. Dann tippe ich halt von Hand "net=tralala" ein oder gebe es aus und markiere es mit der Maus, wenn es sehr viel länger ist und fingerbrechende Sonderzeichenkombinationen enthält. Höchstens elegante oder schnuckelige Workarounds interessieren mich.
Dies hier wäre ein Workaround, der funktioniert und dessen Seiteneffekte mir keine Sorgenfalten bereiten, denn selbst wenn ich eine Subshell aufrufe, verwendet diese wahrscheinlich nicht die Variable "net" und wenn doch, dann wohl in 99% der Fälle genau in dem Sinne.
1 | export $(head -1 test.rc) |
Aber dass es mit export
klappt und ohne nicht finde ich dennoch erklärungsbedürftig. Gut, "export" ist ein Befehl/Programm und "net" ist es nicht, "net=" bzw. "net=something" aber ist m.E. ein Befehl, wenn auch kein Programm und keine Funktion.