J'ai un script bash qui construit une ligne de commande dans une chaîne basée sur certains paramètres avant de l'exécuter en une seule fois. Les parties concaténées à la chaîne de commande sont censées être séparées par des canaux pour faciliter un "streaming" de données à travers chaque composant.
Un exemple très simplifié:
#!/bin/bash
part1=gzip -c
part2=some_other_command
cmd="cat infile"
if [ ! "$part1" = "" ]
then
cmd+=" | $part1"
fi
if [ ! "$part2" = "" ]
then
cmd+=" | $part2"
fi
cmd+="> outfile"
#show command. It looks ok
echo $cmd
#run the command. fails with pipes
$cmd
Pour une raison quelconque, les tuyaux ne semblent pas fonctionner. Lorsque j'exécute ce script, j'obtiens différents messages d'erreur se rapportant généralement à la première partie de la commande (avant le premier canal).
Ma question est donc de savoir s'il est possible de créer une commande de cette manière, et quelle est la meilleure façon de le faire?
infile
existe dans le répertoire actuel?Réponses:
Tout dépend du moment où les choses sont évaluées. Lorsque vous tapez
$cmd
, le reste de la ligne est transmis en tant qu'arguments au premier mot de$cmd
.Cela montre que les arguments passés à la
echo
commande sont: "/etc/passwd
", "|
" (la barre verticale), "wc
" et "-l
".De
man bash
:la source
Une solution à cela, pour référence future, consiste à utiliser "eval". Cela garantit que quelle que soit la façon dont la chaîne est interprétée par bash est oubliée et le tout est lu comme si elle avait été tapée directement dans un shell (ce qui est exactement ce que nous voulons).
Donc, dans l'exemple ci-dessus, remplacer
avec
résolu.
la source
eval foo "a b"
serait le même queeval foo "a" "b"
.@waltinator a déjà expliqué pourquoi cela ne fonctionne pas comme prévu. Une autre solution consiste à utiliser
bash -c
pour exécuter votre commande:la source
bash -c
, mais d'utilisereval
pour faire la commande dans le processus actuel.Peut-être une meilleure façon de le faire est d'éviter d'utiliser
eval
et d' utiliser simplement un tableau Bash et son expansion en ligne pour construire tous les arguments, puis les exécuter contre la commande.la source