So verschachteln Sie Bash-Backticks richtig

91

Entweder habe ich ein Spiel verpasst oder das Spiel scheint nicht mit zu viel Programmierer-Zitat-Schleife zu funktionieren.

$ echo "hello1-`echo hello2-\`echo hello3-\`echo hello4\`\``"

hello1-hello2-hello3-echo hello4

Gesucht

hello1-hello2-hello3-hello4-hello5-hello6-...
hhh
quelle
Die Frage sollte wahrscheinlich "Wie man Bash-Backticks rekursiv verwendet" lauten. Das sollte den Googlern da draußen helfen.
Joey Adams
Was versuchst du zu tun? das hat überhaupt keine bedeutung.
Ghostdog74
1
@joey, Titel geändert, ure willkommen: D
Stormenet
1
Ups, kratz das. Es sollte lauten: "Wie verschachtele ich Backticks in Bash?" . Ich habe Rekursion und Verschachtelung durcheinander gebracht.
Joey Adams
Backticks werden deprecateddaher verwendet $(cmd).
Timo

Antworten:

144

Verwenden Sie $(commands)stattdessen:

$ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
hello1-hello2-hello3-hello4

$(commands) macht das gleiche wie Backticks, aber Sie können sie verschachteln.

Sie könnten auch an Bash-Sortimentserweiterungen interessiert sein:

echo hello{1..10}
hello1 hello2 hello3 hello4 hello5 hello6 hello7 hello8 hello9 hello10
Joey Adams
quelle
+1 wie die {1..10}. Mit Array begrenzen? ZSH kann "$ {$ (Datum) [2,4]}". Warum nicht: "echo $ {echo hello1 - $ (echo hello2) [1]}"?
hhh
35

Wenn Sie darauf bestehen, Backticks zu verwenden, können Sie Folgendes tun

$ echo "hello1-`echo hello2-\`echo hello3-\\\`echo hello4\\\`\``"

Sie müssen Backslashes setzen, \\ \\\\ \\\\\\\\um 2x und so weiter, es ist nur sehr hässlich, verwenden Sie $(commands)wie andere vorgeschlagen.

SIE
quelle
11

Jedes Mal, wenn Sie einen Befehl auswerten möchten, verwenden Sie command substitution:

$(command)

Wenn Sie einen arithmetischen Ausdruck auswerten möchten, verwenden Sie expression substitution:

$((expr))

Sie können diese wie folgt verschachteln:

Angenommen, file1.txt ist 30 Zeilen lang und file2.txt ist 10 Zeilen lang, dann können Sie einen Ausdruck wie diesen auswerten:

$(( $(wc -l file1.txt) - $(wc -l file2.txt) ))

das würde 20 ausgeben (der Unterschied in der Anzahl der Zeilen zwischen zwei Dateien).

toobsco42
quelle
10

Es ist viel einfacher, wenn Sie die $(cmd) Befehlssubstitutionssyntax von bash verwenden, die viel einfacher zu verschachteln ist:

$ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
hello1-hello2-hello3-hello4
Mark Rushakoff
quelle
5
Dies ist nicht auf Bash beschränkt . Es ist in allen Shells verfügbar, die POSIX 1003.1 („POSIX-Shells“) und den meisten von Bourne abgeleiteten Shell ( ksh , ash , dash , bash , zsh usw.) entsprechen, jedoch nicht in der tatsächlichen Bourne-Shell (dh heirloom.sourceforge.net) /sh.html ).
Chris Johnsen
Wow, der Zeitstempel für diese Antwort ist identisch mit dem für die Antwort auf @joey_adams! Synchronität in ihrer wörtlichsten Bedeutung :) Auch hier Upvoting (:
drevicko
0

Manchmal kann das Verschachteln von Backticks durch xargsPipes ersetzt werden

$ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1
hello1 hello2 hello3 hello4

Nachteil dieser Lösung sind:

  • Alle Argumente müssen in umgekehrter Reihenfolge angegeben werden (4 → 1);
  • Alle Argumente werden durch Leerzeichen getrennt (lösbar mit tr):

    $ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1 | tr ' ' '-'
    hello1-hello2-hello3-hello4


Lassen Sie uns einen realen Anwendungsfall zeigen.

Die folgenden Befehle funktionieren in bash, aber nicht in tcsh (das Verschachteln von Backticks wird in tcsh nicht sehr gut gehandhabt).

$ ls $(dirname $(which bash))
$ ls `dirname \`which bash\``

Sie können durch ersetzt werden

$ which bash | xargs dirname | xargs ls
GC
quelle