97 votes

Comment emboîter correctement les backticks de Bash

Soit j'ai raté un retour de bâton, soit le retour de bâton ne semble pas fonctionner avec trop de programmeurs.

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

hello1-hello2-hello3-echo hello4

Recherché

hello1-hello2-hello3-hello4-hello5-hello6-...

0 votes

La question devrait probablement se lire "Comment utiliser les backticks de Bash de manière récursive". Cela devrait aider les Googlers.

0 votes

Qu'est-ce que vous essayez de faire ? Cela n'a aucun sens.

1 votes

@joey, titre modifié, de rien :D

155voto

Joey Adams Points 13049

Utilisez $(commands) à la place :

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

$(commands) fait la même chose que les backticks, mais vous pouvez les imbriquer.

Vous pourriez également être intéressé par les extensions de la gamme Bash :

echo hello{1..10}
hello1 hello2 hello3 hello4 hello5 hello6 hello7 hello8 hello9 hello10

0 votes

+1 comme le {1..10}. Limiter avec un tableau ? ZSH peut "${$( date )[2,4]}". Pourquoi pas : "echo ${echo hello1-$(echo hello2)[1]}" ?

36voto

YOU Points 44812

Si vous insistez pour utiliser des backticks, vous pouvez procéder comme suit

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

vous devez mettre des antislashes, \\ \\\\ \\\\\\\\ par 2x et ainsi de suite, c'est juste très laid, utilisez $(commands) comme d'autres l'ont suggéré.

0 votes

Haha. wow. répondre au niveau plus de 9000

11voto

toobsco42 Points 613

Chaque fois que vous voulez évaluer une commande, utilisez command substitution :

$(command)

Chaque fois que vous voulez évaluer une expression arithmétique, utilisez expression substitution :

$((expr))

Vous pouvez les emboîter comme ceci :

Supposons que le fichier 1.txt comporte 30 lignes et que le fichier 2.txt comporte 10 lignes, vous pouvez alors évaluer une expression comme celle-ci :

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

ce qui donnerait 20 ( la différence en nombre de lignes entre les deux fichiers).

10voto

Mark Rushakoff Points 97350

C'est beaucoup plus facile si vous utilisez l'outil bash $(cmd) syntaxe de substitution des commandes qui est beaucoup plus facile à imbriquer :

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

5 votes

Cela ne se limite pas à bash . Il est disponible dans tous les shells conformes à POSIX 1003.1 ("shells POSIX") et dans la plupart des shells dérivés de Bourne ( ksh , cendres , tableau de bord , bash , zsh etc.) mais pas le shell Bourne proprement dit (c'est-à-dire heirloom.sourceforge.net/sh.html ).

0 votes

Wow, l'horodatage de cette réponse est IDENTIQUE à celui de la réponse de @joey_adams ! La synchronicité dans son sens le plus littéral :) Upvoting ici aussi ( :

1voto

G. C. Points 105

Parfois, l'imbrication des backtick peut être remplacée par xargs et des tuyaux

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

Les inconvénients de cette solution sont les suivants :

  • Tous les arguments doivent être fournis dans l'ordre inverse (4→1) ;
  • Tous les arguments sont séparés par des espaces (soluble avec tr ) :

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

Montrons un cas d'utilisation réel.

Les commandes suivantes fonctionnent en bash, mais pas en tcsh (l'imbrication des backtick n'est pas très bien gérée en tcsh)

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

Ils peuvent être remplacés par

$ which bash | xargs dirname | xargs ls

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X