Systeminformationen:
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)
Scrollen Sie zu den BEISPIELEN unten, wenn Sie nur die vereinfachten Beispiele betrachten möchten, die ich gemacht habe.
HINWEIS: Ich bin kein großer zshBenutzer.
Ich habe mir die fzfTastenkombinationen für bashund angesehen zsh.
Beachten Sie, wie beide einen variablen Befehl ausführen $(__fzfcmd). __fzfcmdStandardmäßig wird die Ausgabe fzfan stdout fzfausgegeben, und die Parametersubstitution führt nur den Befehl ( ) aus, der sich aus der Ausgabe ergibt.
Ein Unterschied zwischen dem bashund dem zshSkript besteht darin, dass bashderjenige die Ausgabe von weiterleitet, sie $(__fzfcmd)jedoch zshnur in einem Array erfasst. Meine Vermutung ist auf ein Problem zurückzuführen, zshbei dem Sie die Ausgabe, fzfan die Sie keine Eingabe vornehmen können, weiterleiten fzfund der Prozess, an den weitergeleitet fzfwird, keine Standardwerte erhält. Ihre einzige Wahl ist zu ^Zoder ^C. ^Cscheint den Prozess aus irgendeinem Grund zu unterstützen. Oder vielleicht wollten sie es einfach in einem Array, damit sie darauf laufen zle vi-fetch-historykönnen . Die bashVersion macht etwas Magie in der Schlüsselbindung mit"\e^": history-expand-line
Jetzt fzfist nicht wichtig. Es scheint, als bräuchten Sie nur ein Programm, das an das ausgegeben wird tty, um durch Parametersubstitution aufgerufen zu werden, um dieses Problem zu verursachen. Ich werde also einige einfachere Beispiele zeigen.
Hier sind einige andere Befehle, die an das ausgegeben werden, das ttydieses Problem verursachen kann zsh:
- vipe (Editor in der Mitte einer Pipe ausführen)
'vim -'(vim von stdin lesen lassen. ähnlich wie vipe, aber nicht an stdout ausgeben)
Ersetzen Sie in den folgenden Beispielen jedes Vorkommen von vipedurch, vim -wenn Sie keine separate Installation durchführen möchten. Denken Sie daran, dass vim -der Editorinhalt nicht wie gewohnt an stdout ausgegeben vipewird.
BEISPIELE:
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
Jetzt frage ich mich hauptsächlich, warum 2)es ein Problem gibt, zshaber nicht für bashund warum 4)und 5)behebt das Problem für zsh.
Die Voraussetzungen für zshdieses Problem scheinen genau das zu sein, was ich in den Titel eingefügt habe:
- Eingangsleitung
- Befehl, der durch Variablen- / Parametersubstitution ausgeführt wird, die
ttyausgegeben wurde - Ausgangsrohr
AKTUALISIEREN
Ich habe eine weitere zshProblemumgehung hinzugefügt , die dieses Problem nicht verursacht 5). Es ist ähnlich, 4)aber anstatt stdoutdirekt umzuleiten stin, leite ich es in eine Datei um, die zur stdinVerwendung der Prozessersetzung umleitet .
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
pszeigt, sind die Muscheln in keinem dieser Fälle eingefroren oder stecken fest. Sie warten einfach auf normale Weise auf untergeordnete Prozesse. und sie werden in der Tat auf normale Weise zur Eingabeaufforderung zurückkehren, sobald diese untergeordneten Prozesse angehalten oder beendet werden. Der Titel und der Text Ihrer Frage enthalten eine implizite falsche Prämisse. "Warum friert meine Muschel ein?" ist eine unbeantwortete geladene Frage, wenn Ihre Shell überhaupt nicht friert. Sie hätten eine bessere Frage, um diese implizite falsche Prämisse zu entfernen.