remplacer le backtick par $ () ne fonctionne pas

17

J'ai d'anciens scripts que j'essaie de mettre à jour. Une partie du code se condense en:

 export X=`(echo "abc"; echo "def")`
 echo $X

ce qui donne la sortie attendue:

 abc def

Maintenant, Internet me dit que les backticks sont supprimés $(), mais que lorsque j'essaie:

export X=$((echo "abc"; echo "def"))

X n'est pas défini et j'obtiens l'erreur:

bash: echo "abc"; echo "def": syntax error: invalid arithmetic operator (error token is ""abc"; echo "def"")

Qu'est-ce que je fais mal?

Harold
la source

Réponses:

27

La $(( … ))syntaxe est une expression arithmétique .

Ce qui manque, c'est un espace entre le $(et le suivant (, pour éviter la syntaxe d'expression arithmétique.

La section sur la substitution de commandes dans la spécification du langage de commande shell avertit en fait:

If the command substitution consists of a single subshell, such as:

   $( (command) )

a conforming application shall separate the "`$(`" and '`(`' into two tokens
(that is, separate them with white space). This is required to avoid any
ambiguities with arithmetic expansion.
Timo
la source
21
Il convient de noter que `...`et $(...)démarrer un sous-shell de toute façon, de sorte que l'intérieur (...)n'est pas nécessaire (gaspiller un processus). Vous auriez besoin d'espace dans des choses comme $( (...); (...) )par exemple (où les sous-coques internes peuvent être nécessaires).
Stéphane Chazelas
15

Essayer export X="$(echo "abc"; echo "def")"

JPG
la source
Merci, cela fonctionne, mais nécessite plus de modifications que l'autre solution.
Harold
2
+1 pour inclure les guillemets nécessaires dans la plupart des shells POSIX ( kshet bashétant les seules exceptions).
Stéphane Chazelas