41 votes

Transférer du texte au programme en attendant un fichier

En relation avec une question que j'ai posée sur Stack Overflow: Passing multiple lines of code to wsadmin.sh?.

J'ai, sous forme de chaîne de caractères, quelques lignes d'entrée que je dois fournir à une commande. Cependant, la commande n'accepte que l'entrée provenant d'un fichier.

Existe-t-il un moyen de stocker les lignes dans un fichier temporaire ou un pipe qui ne sera jamais réellement écrit sur le disque, puis de les transmettre directement au programme?

Comment puis-je créer un pipe, y transmettre l'entrée, passer ce pipe à la commande, puis me débarrasser du pipe?

38voto

ofir_aghai Points 251

Une autre solution est d'utiliser la substitution de processus dans Bash. Si votre système possède des tubes nommés, vous pouvez utiliser cette fonctionnalité.

Cela s'utilise comme ceci :

programme_attendant_un_fichier <(liste)

liste est une séquence de commandes shell (en réalité des pipelines ; les détails complets sont ici). liste sera exécutée et sa sortie sera connectée au tube. Le nom du tube est ensuite passé à votre programme.

NOTE : les espaces ne sont pas autorisés entre < et (.

(L'autre substitution (liste) fonctionne également comme vous vous y attendez.)

Dans votre cas spécifique, vous pourriez utiliser

programme_attendant_un_fichier <(echo "$vos_chaines")

bien que vous puissiez trouver la solution de @meuh plus élégante.

Mise à jour : De nombreux exemples d'utilisation se trouvent sur le Guide avancé de scripts Bash.

20voto

meuh Points 5650

Vous pouvez utiliser un ici-doc bash. Par exemple,

$ cat -n <<<'a
> b'
 1  a
 2  b

Si vous avez quelque chose dans une variable bash vous pouvez aussi l'interpoler: par exemple <<<"chemin est $CHEMIN".


Si votre commande insiste sur un nom de fichier vous pouvez lui donner /dev/stdin. Par exemple:

$ sed -f /dev/stdin <<<'s/a/b/'

produit la sortie: s/b/b/.

7voto

Majenko Points 31077

En fonction de ce qui se trouve dans le script, vous pouvez peut-être utiliser le nom de fichier spécial - (tiret) qui signifie stdin

$ mycmd -
Line 1
Line 2
^D

Une autre méthode qui pourrait fonctionner pour vous est d'ouvrir le fichier /dev/fd/0 qui, là encore, représente stdin.

Une troisième option pourrait être de créer un FIFO (First In First Out). C'est comme un fichier, mais il a deux extrémités - vous écrivez à une extrémité et lisez de l'autre.

-- Processus 1 --                -- Processus 2 --
$ mkfifo foo
$ cat foo
                         $ echo bonjour > foo
bonjour                           $
$ rm foo

4voto

Axel Beckert Points 554

Il existe une autre option similaire à la solution mycmd -, même pour les programmes qui ne gèrent pas spécifiquement le -:

$ mycmd /dev/stdin
Line 1
Line 2
^D

/dev/stdin semble être lié à l'OS et cela fonctionne pour moi sur Debian GNU/Linux, mais je ne sais pas où d'autre cela fonctionnera.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X