web-dev-qa-db-fra.com

Pourquoi la substitution de processus aboutit-elle à un fichier appelé / dev / fd / 63 qui est un canal?

J'essaie de comprendre les canaux nommés dans le contexte de cet exemple particulier.

Je tape <(ls -l) dans mon terminal et j'obtiens la sortie sous la forme bash: /dev/fd/63: Permission denied.

Si je tape cat <(ls -l), je pouvais voir le contenu du répertoire. Si je remplace le cat par echo, je pense que j'obtiens le nom du terminal (ou est-ce?).

echo <(ls -l) donne la sortie sous la forme /dev/fd/63.

De plus, cet exemple de sortie n'est pas clair pour moi.

ls -l <(echo "Whatever")
lr-x------ 1 root root 64 Sep 17 13:18 /dev/fd/63 -> pipe:[48078752]

Cependant, si je donne, ls -l <() il me liste le contenu du répertoire.

Que se passe-t-il en cas de pipe nommée?

42
Ramesh

Lorsque vous effectuez <(some_command), votre shell exécute la commande entre parenthèses et remplace le tout par un descripteur de fichier, qui est connecté à la sortie standard de la commande. Donc /dev/fd/63 Est un canal contenant la sortie de votre appel ls.

Lorsque vous effectuez <(ls -l) vous obtenez une erreur Permission denied, Car toute la ligne est remplacée par le tube, essayant effectivement d'appeler /dev/fd/63 En tant que commande, qui n'est pas exécutable.

Dans votre deuxième exemple, cat <(ls -l) devient cat /dev/fd/63. Au fur et à mesure que cat lit les fichiers donnés comme paramètres, vous obtenez le contenu. echo, en revanche, sort simplement ses paramètres "tels quels".

Le dernier cas que vous avez, <() est simplement remplacé par rien, car il n'y a pas de commande. Mais ce n'est pas cohérent entre les shells, dans zsh vous obtenez toujours un pipe (bien que vide).

Résumé : <(command) vous permet d'utiliser la sortie d'une commande, où vous auriez normalement besoin d'un fichier.

Edit: as Gilles fait remarquer, ce n'est pas un canal nommé, mais un canal anonyme. La principale différence est qu'il n'existe que tant que le processus est en cours d'exécution, tandis qu'un canal nommé (créé par exemple avec mkfifo) restera sans processus attaché.

38
crater2150