Informazioni di sistema:
macOS Sierra 10.12.6
zsh 5.4.2 (x86_64-apple-darwin16.7.0)
GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.3.0)
Scorri fino agli ESEMPI in basso se vuoi solo approfondire gli esempi semplificati che ho fatto.
NOTA: non sono un grande zshutente.
Stavo guardando le fzfcombinazioni di tasti per bashe zsh.
Notare come entrambi eseguono un comando variabile $(__fzfcmd). __fzfcmdper impostazione predefinita output fzfsu stdout e la sostituzione dei parametri esegue semplicemente command ( fzf) risultante dall'output.
Una differenza tra lo script bashe zshè che bashquello convoglia ulteriormente l'output di $(__fzfcmd)ma zshlo cattura semplicemente all'interno di un array. La mia ipotesi è dovuta a un problema in zshcui si esegue ulteriormente il piping dell'output in fzfcui non è possibile immettere fzfe il processo a cui viene eseguito il piping fzfnon ottiene alcuno stdin. La tua unica scelta è di ^Zo ^C. ^Csembra fare da sfondo al processo per qualche motivo. O forse volevano solo in una matrice in modo che potessero potessero funzionare zle vi-fetch-historysu di esso . La bashversione fa un po 'di magia nel key binding con"\e^": history-expand-line
Adesso fzfnon è importante. Sembra che tu abbia solo bisogno di un programma che emetta l'output ttyper essere chiamato dalla sostituzione dei parametri per causare questo problema. Quindi mostrerò alcuni esempi più semplici.
Ecco alcuni altri comandi che ttygenerano in output che possono causare questo problema in zsh:
- vipe (esegui l'editor nel mezzo di una pipe)
'vim -'(fai in modo che vim legga da stdin. simile a vipe ma non verrà riprodotto in stdout)
Negli esempi seguenti, sostituire ogni occorrenza di vipecon vim -se non si desidera eseguire un'installazione separata. Ricorda solo che vim -il contenuto dell'editor non verrà riprodotto su stdout come vipefa.
ESEMPI:
1) echo 1 | vipe | cat # works in both bash and zsh
2) echo 1 | $(echo vipe) | cat # works in bash only. zsh problem with no output until I hit `^C`:
^C
zsh: done echo 1 |
zsh: suspended (tty output) $(echo vipe) |
zsh: interrupt cat
# seems like the process is backgrounded. I can still see it in jobs command
3) cat <(echo 1 | $(echo vipe)) # zsh and bash has the problem. I'm guessing because
# the file isn't finished writing and cat is
# blocking vipe's tty output
# both their `^C` output is just:
^C # nothing special, as expected
4) cat < <(echo 1 | $(echo vipe)) # works in both bash and zsh
5) echo 1 | $(echo vipe) > >(cat) # works in both bash and zsh
# The following don't have and input pipe to vipe.
# Type something then send EOF with ^D
6) vipe | cat # works for both
7) $(echo vipe) | cat # works for both
Ora, mi chiedo principalmente perché 2)abbia un problema per zshma non per bashe perché 4)e 5)risolva il problema per zsh.
I requisiti per zshavere questo problema sembrano essere esattamente ciò che ho inserito nel titolo:
- tubo di ingresso
- comando eseguito dalla sostituzione variabile / parametro che ha
ttygenerato - tubo di uscita
AGGIORNARE
Ho aggiunto un'altra soluzione che non causare zshad avere questo problema, 5). È simile 4)ma invece di reindirizzare stdoutdirettamente in stin, lo reindirizzo in un file che reindirizza stdinall'utilizzo della sostituzione del processo.
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
psti dirà, in nessuno di questi casi i gusci sono congelati o bloccati. Stanno semplicemente aspettando i processi figlio in modo normale; e torneranno sicuramente a richiedere input nel modo normale una volta che quei processi figlio sono sospesi o chiusi. Il titolo e il corpo della domanda includono una premessa implicita falsa. "Perché la mia shell si blocca?" è una domanda caricata senza risposta quando la shell non si blocca in primo luogo. Avresti una domanda migliore per rimuovere questa premessa implicita falsa.