Information système:
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)
Faites défiler jusqu'aux EXEMPLES en bas si vous voulez simplement vous plonger dans les exemples simplifiés que j'ai faits.
REMARQUE: je ne suis pas un grand zshutilisateur.
Je regardais les fzfraccourcis clavier pour bashet zsh.
Remarquez comment ils exécutent tous deux une commande variable $(__fzfcmd). __fzfcmdpar défaut, les sorties fzfvers stdout et la substitution de paramètres exécute simplement la commande ( fzf) résultant de la sortie.
Une différence entre le script bashet zshest que celui- bashci redirige la sortie de $(__fzfcmd)mais la zshcapture simplement dans un tableau. Ma supposition est due à un problème zshlorsque vous dirigez la sortie d' fzfoù vous ne pouvez pas entrer fzfet que le processus dirigé vers par fzfn'obtient pas de stdin. Votre seul choix est de ^Zou ^C. ^Csemble expliquer le processus pour une raison quelconque. Ou peut-être qu'ils le voulaient simplement dans un tableau afin de pouvoir fonctionner zle vi-fetch-historydessus . La bashversion fait un peu de magie dans le raccourci clavier avec"\e^": history-expand-line
Ce fzfn'est pas important maintenant . Il semble que vous ayez juste besoin d'un programme qui renvoie vers le ttypour être appelé par substitution de paramètres pour provoquer ce problème. Je vais donc montrer quelques exemples plus simples.
Voici quelques autres commandes qui sortent vers le ttyqui peuvent provoquer ce problème dans zsh:
- vipe (exécuter l'éditeur au milieu d'un tuyau)
'vim -'(faire lire vim depuis stdin. similaire à vipe mais ne pas sortir vers stdout)
Dans les exemples ci-dessous, remplacez chaque occurrence de vipepar vim -si vous ne souhaitez pas effectuer une installation distincte. N'oubliez vim -pas que le contenu de l'éditeur ne sortira pas sur stdout comme le vipefait.
EXEMPLES:
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
Maintenant, je me demande surtout pourquoi 2)a un problème pour zshmais pas pour bashet pourquoi 4)et 5)résout le problème pour zsh.
Les exigences pour zshavoir ce problème semblent être exactement ce que j'ai mis dans le titre:
- tuyau d'entrée
- commande exécutée par substitution de variable / paramètre qui a une
ttysortie - tuyau de sortie
METTRE À JOUR
J'ai ajouté une autre solution qui ne provoque pas zshd'avoir ce problème, 5). C'est similaire 4)mais au lieu de rediriger stdoutdirectement vers stin, je le redirige dans un fichier qui redirige vers l' stdinutilisation de la substitution de processus.
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
psvous le dira, dans aucun de ces cas, les coquilles ne sont gelées ou bloquées. Ils attendent simplement les processus enfants de la manière normale; et ils reviendront en effet à l'invite de saisie de la manière normale une fois que ces processus enfants seront suspendus ou terminés. Le titre et le corps de votre question contiennent une fausse prémisse implicite. "Pourquoi ma coquille gèle-t-elle?" est une question chargée sans réponse lorsque votre shell ne gèle pas en premier lieu. Vous auriez une meilleure question pour supprimer cette fausse prémisse implicite.