系统信息:
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)
滚动到示例在底部,如果你只是想挖成简单的例子,我做。
注意:我不是一个大zsh
用户。
注意它们都是如何运行可变命令的$(__fzfcmd)
。__fzfcmd
默认情况下,输出fzf
到stdout,并且参数替换仅运行fzf
由输出产生的命令()。
bash
和zsh
脚本之间的区别是,bash
另一个脚本通过管道传递输出,$(__fzfcmd)
但zsh
仅将其捕获到数组中。我的猜测是由于一个问题,zsh
当您进一步通过管道传输fzf
无法输入的位置的输出时,fzf
通过管道传输到的过程fzf
不会得到任何标准输入。您唯一的选择是to ^Z
或^C
。^C
由于某种原因,似乎使该过程成为背景。或者,也许他们只是想以阵列的形式使用它们,以便可以在其上运行zle vi-fetch-history
。该bash
版本在与"\e^": history-expand-line
现在fzf
并不重要。似乎您只需要一个输出到的程序tty
就可以通过参数替换来调用该程序,从而导致此问题。因此,我将显示一些更简单的示例。
这是一些其他输出到的命令,这些命令tty
可能会导致以下问题zsh
:
- vipe(在管道中间运行编辑器)
'vim -'
(使vim从stdin读取。类似于vipe,但不会输出到stdout)
在下面的例子中,更换的每次出现vipe
用vim -
,如果你不想做一个单独的安装。只是要记住,vim -
不会像vipe
那样将编辑器内容输出到stdout 。
例子:
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
现在,我主要是想知道为什么2)
有一个问题zsh
,但不是bash
,为什么4)
和5)
修复问题zsh
。
对于要求zsh
有这个问题似乎正是我把标题:
- 输入管
- 由具有
tty
输出的变量/参数替换运行的命令 - 输出管
更新
我添加了另一个不会导致zsh
此问题的解决方法5)
。它类似于4)
但不stdout
直接重定向到stin
,而是将其重定向到stdin
使用流程替换重定向到的文件。
(echo | $(echo vipe) | cat)
ps
将告诉您的那样,在所有这些情况下,都不会将外壳冻结或卡住。他们只是以正常方式等待子进程。并且一旦这些子进程被挂起或终止,它们的确会循环回以正常方式提示输入。您的问题标题和正文包含一个隐含的假前提。“为什么我的贝壳冻结了?” 当您的外壳最初没有真正冻结时,这是一个无法回答的加载问题。对于删除此隐式错误前提,您会有更好的问题。