En zsh, diferencia entre cat <(cat) vs cat | gato vs gato = (gato)?

18

Esperaba cat <(cat)y cat | cathacer lo mismo: copiar líneas de stdin a stdout. Comprendí que ambos ejecutarían un caten una subshell, redirigirían el catstdout de la subshell a una tubería con nombre temporal y luego ejecutarían otro caten la shell actual con su stdin redirigido a la tubería.

En cambio, cat <(cat)me permite escribir en mi terminal, pero ninguna de las líneas de entrada se copia y ^Dno puede señalizar EOF; cat | catfunciona como se esperaba sin embargo.

Como otro experimento, verifiqué si cat =(cat)tiene dificultades similares cat <(cat), pero funciona como esperaba: todo el stdin hasta un ^Dse copia en stdout de una vez.

¿Alguien puede ayudarme a entender qué está haciendo zsh bajo el capó?

Alan O'Donnell
fuente

Respuestas:

23
  1. a | bse conecta STDOUTdesde ay STDINdesde bsimplemente usando dup/dup2. Ambos comandos se ejecutan en paralelo.

  2. a =(b)reemplaza el argumento a acon un nombre de archivo temporal. bse ejecutará antes aya que el archivo temporal debe crearse antes de que pueda pasarse aa

  3. a <(b)reemplaza el argumento a acon una tubería con nombre. ay bcorrer en paralelo Aquí es donde se pone un poco complicado:

    bestá en segundo plano y no puede leer desde la terminal. Puede probarlo usted mismo strace -p $PIDpara adjuntarlo a su segundo proceso de gato para ver el proceso.

    amientras tanto, intenta leer desde la tubería con nombre pero no puede leer nada como bno puede leer.

    • Esto significa que básicamente tiene un punto muerto donde aintenta leer bpero bno puede leer STDINy no puede escribir ena

Más información sobre el proceso en segundo plano y la terminal de man bash :

Para facilitar la implementación de la interfaz de usuario para el control del trabajo, el sistema operativo mantiene la noción de una ID de grupo de proceso de terminal actual . Los miembros de este grupo de procesos (procesos cuyo ID de grupo de proceso es igual al ID de grupo de proceso de terminal actual) reciben señales generadas por el teclado, como SIGINT . Se dice que estos procesos están en primer plano . Antecedenteslos procesos son aquellos cuya ID de grupo de procesos difiere de la terminal; tales procesos son inmunes a las señales generadas por el teclado. Solo los procesos en primer plano pueden leer o, si el usuario así lo especifica con stty tostop, escribir en el terminal. Los procesos en segundo plano que intentan leer (escribir en cuando stty tostop está en efecto) el terminal reciben una señal SIGTTIN (SIGTTOU) por el controlador de terminal del kernel, que, a menos que se detecte, suspende el proceso.

Ulrich Dangel
fuente
Genial, gracias, ¡esto se aclaró mucho!
Alan O'Donnell
1
Tenga en cuenta que cuando no es interactivo, zsh redirige la entrada estándar de los comandos de fondo (incluidos los de <(cmd)) /dev/null, por lo que el comportamiento difiere ( zsh -c 'cat <(cat)'regresa de inmediato y no genera nada).
Stéphane Chazelas