web-dev-qa-db-fra.com

Transmettre du texte au programme dans l'attente d'un fichier

En lien avec une question que j'ai posée sur le dépassement de pile: Passage de plusieurs lignes de code dans wsadmin.sh? .

J'ai, sous forme de chaîne, quelques lignes d'entrée dont j'ai besoin pour alimenter une commande. La commande n'accepte cependant qu'un fichier complet.

Existe-t-il un moyen de stocker les lignes dans un fichier temporaire ou un canal qui n’est jamais réellement écrit sur le disque, puis directement dans le programme?

Comment puis-je acquérir le tuyau, y introduire les données, le transmettre à la commande, puis le supprimer?

29
ArtOfWarfare

Une autre solution consiste à utiliser la substitution de processus dans Bash. Si votre système a nommé des canaux, vous pouvez utiliser cette fonctionnalité.

Il est utilisé comme ceci:

program_expecting_a_file <(list)

list est une séquence de commandes Shell (en fait, les pipelines; tous les détails sont ici ). list sera exécuté et sa sortie sera connectée au tuyau. Le nom du tuyau est ensuite transmis à votre programme.

REMARQUE: Les espaces ne sont pas autorisés entre < et (.

(L'autre substitution >(list) fonctionne également comme prévu.)

Dans votre cas particulier, vous pourriez utiliser

program_expecting_a_file <(echo "$your_strings")

bien que la solution de @ meuh soit peut-être plus élégante.

Mise à jour: Vous trouverez un grand nombre d’exemples d’utilisation dans le Guide de script avancé de Bash .

25
Edward

Vous pouvez utiliser un bash ici-doc . 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 <<<"path is $PATH".


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/.

13
meuh

Selon le contenu du script, vous pourrez pouvoir utiliser le nom de fichier spécial - (moins), qui signifie stdin

$ mycmd -
Line 1
Line 2
^D

Une autre méthode qui peut fonctionner pour vous consiste à ouvrir le fichier /dev/fd/0 qui correspond encore à stdin .

Une troisième option peut être de créer un FIFO (premier entré, premier sorti). Cela ressemble à un fichier, mais il a deux extrémités: vous écrivez à une extrémité et lisez à partir de l'autre.

-- Process 1 --                  -- Process 2 --
$ mkfifo foo
$ cat foo
<waits>                          $ echo hello > foo
hello                            $
$ rm foo
7
Majenko

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

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

/dev/stdin semble être lié au système d'exploitation et cela fonctionne pour moi sous Debian GNU/Linux, mais je ne sais pas trop si cela fonctionnera aussi.

3
Axel Beckert