Certains shells, comme bash
, prennent en charge la substitution de processus qui est un moyen de présenter la sortie du processus sous forme de fichier, comme ceci:
$ diff <(sort file1) <(sort file2)
Cependant, cette construction n'est pas POSIX et, par conséquent, n'est pas portable. Comment peut-on réaliser la substitution de processus d'une manière respectueuse de POSIX (c'est-à-dire qui fonctionne /bin/sh
) ?
Remarque: la question n'est pas de savoir comment différencier deux fichiers triés - ce n'est qu'un exemple artificiel pour démontrer la substitution de processus !
shell
pipe
posix
process-substitution
étoilé
la source
la source
/bin/sh
d'être un shell POSIX, seulement qu'il y ait une commande appeléesh
quelque part qui dans le bon environnement est compatible POSIX. Par exemple, sur Solaris 10, ce/bin/sh
n'est pas un shell POSIX, c'est un ancien shell Bourne et le shell POSIX est dedans/usr/xpg4/bin/sh
.Réponses:
Cette fonctionnalité a été introduite par
ksh
(d'abord documentée dans ksh86) et utilisait la/dev/fd/n
fonctionnalité (ajoutée indépendamment dans certains systèmes BSD et AT&T plus tôt). Dansksh
et jusqu'à ksh93u, cela ne fonctionnerait que si votre système prenait en charge / dev / fd / n. zsh, bash etksh93u+
plus peuvent utiliser des canaux nommés temporaires (des canaux nommés ajoutés dans SysIII je crois) où / dev / fd / n ne sont pas disponibles.Sur les systèmes où est disponible (POSIX ne le spécifie pas), vous pouvez effectuer vous-même la substitution de processus ( ) avec:
/dev/fd/n
diff <(cmd1) <(cmd2)
Cependant, cela ne fonctionne pas avec
ksh93
Linux car là-bas, les canaux shell sont implémentés avec des paires de sockets au lieu de canaux et l'ouverture/dev/fd/3
où fd 3 pointe vers un socket ne fonctionne pas sous Linux.Bien que POSIX ne le spécifie pas . Il spécifie les canaux nommés. Les canaux nommés fonctionnent comme les canaux normaux, sauf que vous pouvez y accéder à partir du système de fichiers. Le problème ici est que vous devez créer des fichiers temporaires et nettoyer par la suite, ce qui est difficile à faire de manière fiable, d'autant plus que POSIX n'a pas de mécanisme standard (comme celui que l'on trouve sur certains systèmes) pour créer des fichiers ou des répertoires temporaires et effectuer la gestion des signaux de manière portable (pour nettoyer après avoir raccroché ou tué) est également difficile à faire de manière portable.
/dev/fd/n
mktemp -d
Vous pourriez faire quelque chose comme:
(ne s'occupe pas du traitement du signal ici).
la source
/dev/fd/n
exemple. Pourquoi le descripteur 4 est-il fermé deux fois? (Et le descripteur 3 aussi.) Je suis perdu.cmd2
(dup2(0,4)
à l'extérieur{...}
, restauré avecdup2(4,0)
pour l'intérieur{...}
).mktemp -d
pour vous assurer d'obtenir des FIFO, car personne ne devrait écrire dans votre tout nouveau répertoire temporaire aléatoire.mktemp -d
. Mais ce n'est pas une commande standard / POSIX.Si nécessaire pour éviter la perte de variable dans l'utile
cmd | while read A B C
, au lieu de:vous pouvez utiliser:
Donc pour répondre à la question:
la source