web-dev-qa-db-fra.com

Comment passer la valeur d'une variable au stdin d'une commande?

J'écris un script Shell qui devrait être quelque peu sécurisé, c'est-à-dire qu'il ne transmet pas de données sécurisées via les paramètres de commandes et n'utilise de préférence pas de fichiers temporaires. Comment puis-je passer une variable au stdin d'une commande? Ou, si ce n'est pas possible, comment utiliser correctement les fichiers temporaires pour une telle tâche?

87
user283145

Quelque chose d'aussi simple que:

echo "$blah" | my_cmd
67
Oliver Charlesworth

Passer une valeur sur stdin est aussi simple que:

your-command <<< "$your_variable"

Assurez-vous de toujours mettre des guillemets autour d'expressions variables!

156
Martin

Notez que le 'echo "$var" | command opérations signifie que l’entrée standard est limitée à la ou aux lignes en écho. Si vous souhaitez également que le terminal soit connecté, vous devez être plus sophistiqué:

{ echo "$var"; cat - ; } | command

( echo "$var"; cat -   ) | command

Cela signifie que la ou les premières lignes seront le contenu de $var mais le reste viendra de cat lisant son entrée standard. Si la commande ne fait rien de trop sophistiqué (essayez d'activer l'édition en ligne de commande, ou exécutez comme vim le fait), alors tout ira bien. Sinon, vous devez être vraiment chic - je pense que expect ou l’un de ses dérivés est susceptible de convenir.

Les notations en ligne de commande sont pratiquement identiques, mais le deuxième point-virgule est nécessaire avec les accolades alors qu'il ne l'est pas entre parenthèses.

17
Jonathan Leffler
(cat <<END
$passwd
END
) | command

cat n'est pas vraiment nécessaire, mais il aide à mieux structurer le code et vous permet d'utiliser davantage de commandes entre parenthèses en tant qu'entrée de votre commande.

15
PoltoS

J'ai aimé la réponse de Martin, mais cela pose quelques problèmes en fonction de ce que contient la variable. Cette

your-command <<< """$your_variable"""

est mieux si votre variable contient "ou!

13
Robert Jacobs

Selon la réponse de Martin, il existe une fonctionnalité bash appelée Here Strings (qui est elle-même une variante du plus largement pris en charge Voici la fonction Documents ).

http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings

3.6.7 Ici les cordes

Une variante de ces documents, le format est:

<<< Word

Le mot est développé et fourni à la commande sur son entrée standard.

Notez que Here Strings semblerait être uniquement en bash. Par conséquent, pour améliorer la portabilité, il serait probablement préférable d'utiliser la fonctionnalité Here Documents originale, comme indiqué dans la réponse de PoltoS:

( cat <<EOF
$variable
EOF
) | cmd

Ou, une variante plus simple de ce qui précède:

(cmd <<EOF
$variable
EOF
)

Vous pouvez omettre ( et ), à moins que vous ne souhaitiez que cela soit redirigé davantage vers d'autres commandes.

7
cnst

Essaye ça:

echo "$variable" | command
4
unbeli

Ce moyen robuste et portable est déjà apparu dans les commentaires. Ce devrait être une réponse autonome.

printf '%s' "$var" | my_cmd

ou

printf '%s\n' "$var" | my_cmd

Remarques:

  • C'est mieux que echo, les raisons sont les suivantes: Pourquoi printf est-il meilleur que echo?
  • printf "$var" est faux. Le premier argument est le format où différentes séquences comme %s ou \n sont interprétés . Pour passer la variable à droite, elle ne doit pas être interprétée comme un format.
  • Généralement, les variables ne contiennent pas de retour à la ligne. L'ancienne commande (avec %s) transmet la variable telle quelle. Cependant, les outils qui fonctionnent avec du texte peuvent ignorer ou se plaindre d'une ligne incomplète (voir Pourquoi les fichiers texte doivent-ils se terminer par une nouvelle ligne? ). Donc, vous voudrez peut-être la dernière commande (avec %s\n) qui ajoute un caractère de nouvelle ligne au contenu de la variable. Faits non évidents:

    • Ici la chaîne dans Bash (<<<"$var" my_cmd) ajoute une nouvelle ligne.
    • Toute méthode qui ajoute une nouvelle ligne donne un stdin non vide de my_cmd, même si la variable est vide ou non définie.
1