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 zsh
Benutzer.
Ich habe mir die fzf
Tastenkombinationen für bash
und angesehen zsh
.
Beachten Sie, wie beide einen variablen Befehl ausführen $(__fzfcmd)
. __fzfcmd
Standardmäßig wird die Ausgabe fzf
an stdout fzf
ausgegeben, und die Parametersubstitution führt nur den Befehl ( ) aus, der sich aus der Ausgabe ergibt.
Ein Unterschied zwischen dem bash
und dem zsh
Skript besteht darin, dass bash
derjenige die Ausgabe von weiterleitet, sie $(__fzfcmd)
jedoch zsh
nur in einem Array erfasst. Meine Vermutung ist auf ein Problem zurückzuführen, zsh
bei dem Sie die Ausgabe, fzf
an die Sie keine Eingabe vornehmen können, weiterleiten fzf
und der Prozess, an den weitergeleitet fzf
wird, keine Standardwerte erhält. Ihre einzige Wahl ist zu ^Z
oder ^C
. ^C
scheint den Prozess aus irgendeinem Grund zu unterstützen. Oder vielleicht wollten sie es einfach in einem Array, damit sie darauf laufen zle vi-fetch-history
können . Die bash
Version macht etwas Magie in der Schlüsselbindung mit"\e^": history-expand-line
Jetzt fzf
ist 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 tty
dieses 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 vipe
durch, vim -
wenn Sie keine separate Installation durchführen möchten. Denken Sie daran, dass vim -
der Editorinhalt nicht wie gewohnt an stdout ausgegeben vipe
wird.
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, zsh
aber nicht für bash
und warum 4)
und 5)
behebt das Problem für zsh
.
Die Voraussetzungen für zsh
dieses Problem scheinen genau das zu sein, was ich in den Titel eingefügt habe:
- Eingangsleitung
- Befehl, der durch Variablen- / Parametersubstitution ausgeführt wird, die
tty
ausgegeben wurde - Ausgangsrohr
AKTUALISIEREN
Ich habe eine weitere zsh
Problemumgehung hinzugefügt , die dieses Problem nicht verursacht 5)
. Es ist ähnlich, 4)
aber anstatt stdout
direkt umzuleiten stin
, leite ich es in eine Datei um, die zur stdin
Verwendung der Prozessersetzung umleitet .
ps
zeigt, 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.when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
Antworten:
Ich glaube, Ihr Problem läuft darauf hinaus, Ihre Erweiterungen falsch zu zitieren.
Zitat aus zsh: 14 Erweiterung
Beachten Sie, dass Beispiel 2 in Ihrer Frage zu einem unendlichen Echo von NULL führt, und zwar aufgrund von:
Mit anderen Worten, die Shell wartet unendlich auf das
echo
, da das Standardtrennzeichen SPACE ist und das Echo niemals abgeschlossen wird. Siehe TLDP: Interne Variablen . Dadurch bleibt eine Rohrleitung für dencat
Befehl hängen .Als Vermutung glaube ich, dass 4 und 5 aufgrund der Ausgabeumleitung funktionieren.
quelle