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 zsh
utilisateur.
Je regardais les fzf
raccourcis clavier pour bash
et zsh
.
Remarquez comment ils exécutent tous deux une commande variable $(__fzfcmd)
. __fzfcmd
par défaut, les sorties fzf
vers stdout et la substitution de paramètres exécute simplement la commande ( fzf
) résultant de la sortie.
Une différence entre le script bash
et zsh
est que celui- bash
ci redirige la sortie de $(__fzfcmd)
mais la zsh
capture simplement dans un tableau. Ma supposition est due à un problème zsh
lorsque vous dirigez la sortie d' fzf
où vous ne pouvez pas entrer fzf
et que le processus dirigé vers par fzf
n'obtient pas de stdin. Votre seul choix est de ^Z
ou ^C
. ^C
semble 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-history
dessus . La bash
version fait un peu de magie dans le raccourci clavier avec"\e^": history-expand-line
Ce fzf
n'est pas important maintenant . Il semble que vous ayez juste besoin d'un programme qui renvoie vers le tty
pour ê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 tty
qui 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 vipe
par 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 vipe
fait.
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 zsh
mais pas pour bash
et pourquoi 4)
et 5)
résout le problème pour zsh
.
Les exigences pour zsh
avoir 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
tty
sortie - tuyau de sortie
METTRE À JOUR
J'ai ajouté une autre solution qui ne provoque pas zsh
d'avoir ce problème, 5)
. C'est similaire 4)
mais au lieu de rediriger stdout
directement vers stin
, je le redirige dans un fichier qui redirige vers l' stdin
utilisation de la substitution de processus.
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
ps
vous 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.