In zsh, differenza tra cat <(cat) vs cat | cat vs cat = (cat)?


18

Mi aspettavo cat <(cat)e cat | catfare la stessa cosa: copiare le righe da stdin a stdout. La mia comprensione era che entrambi avrebbero eseguito a catin una subshell, reindirizzando lo catstdout della subshell a una pipe denominata temporanea e quindi eseguendo un'altra catnella shell corrente con il suo stdin reindirizzato alla pipe.

Invece, cat <(cat)mi permette di digitare sul mio terminale, ma nessuna delle linee di input viene copiata e ^Dnon riesce a segnalare EOF; cat | catfunziona come previsto però.

Come ulteriore esperimento, ho verificato se cat =(cat)ha difficoltà simili cat <(cat), ma funziona come mi aspettavo: tutto lo stdin fino a uno ^Dviene copiato nello stdout in una volta sola.

Qualcuno può aiutarmi a capire cosa sta facendo zsh sotto il cofano?

Risposte:


23
  1. a | bsi collega STDOUTda ae STDINverso bsemplicemente usando dup/dup2. Entrambi i comandi vengono eseguiti in parallelo.

  2. a =(b)sostituisce l'argomento acon un nome file temporaneo. bverrà eseguito prima apoiché è necessario creare il file temporaneo prima di poterlo passarea

  3. a <(b)sostituisce l'argomento acon una pipe denominata. aed beseguire in parallelo. Ora è qui che diventa un po 'complicato:

    bè in background e non può leggere dal terminale. Puoi testarlo tu stesso usando strace -p $PIDper collegarti al tuo secondo processo cat per vedere il processo.

    anel frattempo cerca di leggere dalla pipe nominata ma non riesce a leggere nulla come bnon può leggere.

    • Ciò significa che in pratica si ha un deadlock nel quale si atenta di leggere bma bnon è possibile leggere STDINe non è possibile scriverea

Maggiori informazioni sul processo in background e sul terminale da man bash :

Per facilitare l'implementazione dell'interfaccia utente per il controllo dei lavori, il sistema operativo mantiene l'idea di un ID gruppo di processi terminale corrente . I membri di questo gruppo di processi (processi il cui ID gruppo di processi è uguale all'attuale ID gruppo di processi terminale) ricevono segnali generati da tastiera come SIGINT . Si dice che questi processi siano in primo piano . sfondoi processi sono quelli il cui ID gruppo di processi differisce da quello del terminale; tali processi sono immuni ai segnali generati dalla tastiera. Solo i processi in primo piano possono leggere o, se l'utente lo specifica con stty tostop, scrivere sul terminale. I processi in background che tentano di leggere (scrivere su quando è attivo stosto tostop) al terminale viene inviato un segnale SIGTTIN (SIGTTOU) dal driver del terminale del kernel, che, se non intercettato, sospende il processo.


Fantastico, grazie - tutto chiarito!
Alan O'Donnell,

1
Nota quando non interattivo, zsh reindirizza l'input standard dei comandi in background (inclusi quelli in <(cmd)) /dev/null, quindi il comportamento differisce ( zsh -c 'cat <(cat)'ritorna immediatamente e non genera nulla).
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.