En zsh, différence entre cat <(cat) vs cat | chat vs chat = (chat)?


18

Je m'y attendais cat <(cat)et cat | catde faire la même chose: copier des lignes de stdin stdout. Ma compréhension était que les deux exécuteraient un catdans un sous-shell, redirigeraient la sortie catstandard du sous-shell vers un tube nommé temporaire, puis en exécuteraient un autre catdans le shell actuel avec son stdin redirigé vers le tube.

Au lieu de cela, cat <(cat)permet de taper sur mon terminal, mais aucune des lignes d'entrée n'est copiée et ^Dne parvient pas à signaler EOF; cat | catfonctionne comme prévu cependant.

Comme une autre expérience, j'ai vérifié si cat =(cat)a des difficultés similaires cat <(cat), mais cela fonctionne comme prévu: tous les stdin jusqu'à un ^Dsont copiés dans stdout en une seule fois.

Quelqu'un peut-il m'aider à comprendre ce que zsh fait sous le capot?

Réponses:


23
  1. a | bse connecte STDOUTdepuis aet STDINdepuis bsimplement en utilisant dup/dup2. Les deux commandes sont exécutées en parallèle.

  2. a =(b)remplace l'argument to apar un nom de fichier temporaire. bsera exécuté avant acar le fichier temporaire doit être créé avant de pouvoir être transmis àa

  3. a <(b)remplace l'argument to apar un canal nommé. aet bfonctionner en parallèle. C'est maintenant que cela devient un peu compliqué:

    best en arrière-plan et ne peut pas lire depuis le terminal. Vous pouvez le tester vous-même en utilisant strace -p $PIDpour attacher à votre deuxième processus de chat pour voir le processus.

    aen attendant, essaie de lire à partir du canal nommé mais ne peut rien lire car as bne peut pas lire.

    • Cela signifie que vous avez fondamentalement un blocage où aessaie de lire bmais bne peut pas lire STDINet ne peut pas écrire dansa

Plus d'informations sur le processus d'arrière-plan et le terminal de man bash :

Pour faciliter la mise en œuvre de l'interface utilisateur pour le contrôle des travaux, le système d'exploitation conserve la notion d' ID de groupe de processus terminal actuel . Les membres de ce groupe de processus (processus dont l'ID de groupe de processus est égal à l'ID de groupe de processus terminal actuel) reçoivent des signaux générés par le clavier tels que SIGINT . Ces processus seraient au premier plan . Contexteles processus sont ceux dont l'ID de groupe de processus diffère de celui du terminal; ces processus sont immunisés contre les signaux générés par le clavier. Seuls les processus de premier plan sont autorisés à lire ou, si l'utilisateur le souhaite avec stty tostop, à écrire sur le terminal. Les processus en arrière-plan qui tentent de lire (écrire sur quand stty tostop est en vigueur) le terminal reçoivent un signal SIGTTIN (SIGTTOU) par le pilote de terminal du noyau, qui, à moins qu'il ne soit intercepté, suspend le processus.


Super, merci - cela a beaucoup éclairci!
Alan O'Donnell

1
Notez que lorsqu'il n'est pas interactif, zsh redirige l'entrée standard des commandes d' arrière - plan (y compris celles en <(cmd)) vers /dev/null, de sorte que le comportement diffère ( zsh -c 'cat <(cat)'retourne immédiatement et ne produit rien).
Stéphane Chazelas
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.