dos*_*ter 14 bash zsh pipe tty
系统信息:
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)
Run Code Online (Sandbox Code Playgroud)
滚动到示例在底部,如果你只是想挖成简单的例子,我做。
注意:我不是一个大zsh用户。
注意它们是如何运行可变命令的$(__fzfcmd)。__fzfcmd默认情况下输出fzf到 stdout 并且参数替换仅运行fzf由输出产生的命令 ( )。
bash和zsh脚本之间的一个区别是,bash它进一步通过管道传输 的输出,$(__fzfcmd)但zsh只是将其捕获在数组中。我的猜测是因为zsh当您进一步将fzf无法输入的输出fzf通过管道传输到并且通过管道传输到的进程fzf没有获得任何标准输入时出现问题。您唯一的选择是^Z或^C。^C似乎出于某种原因使该过程成为背景。或者也许他们只是想将它放在一个数组中,以便他们可以在它上面运行zle vi-fetch-history。该bash版本在键绑定中做了一些魔法"\e^": history-expand-line
现在fzf不重要。似乎您只需要一个程序来输出tty到要通过参数替换调用的 来导致此问题。所以我将展示一些更简单的例子。
以下是输出到tty可能导致此问题的其他一些命令zsh:
'vim -' (使 vim 从标准输入读取。类似于 vipe,但不会输出到标准输出)在下面的示例中,如果您不想进行单独安装,请将出现的每个替换为vipewith vim -。请记住,vim -不会像vipe那样将编辑器内容输出到标准输出。
例子:
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
Run Code Online (Sandbox Code Playgroud)
现在,我主要是想知道为什么2)有一个问题zsh,但不是bash,为什么4)和5)修复问题zsh。
对于要求zsh有这个问题似乎正是我把标题:
tty输出的变量/参数替换运行的命令更新
我添加了另一个不会导致zsh出现此问题的解决方法,5). 它类似于4)但不是stdout直接重定向到stin,而是将其重定向到一个文件中,该文件重定向到stdin使用进程替换。
我相信你的问题归结为不正确地引用你的扩展。
\n\n引用自zsh:14 扩展
\n\n\n\n\n括在括号中且前面带有美元符号的命令(例如 \n
\n$(...))或用重音符号引用(例如 \xe2\x80\x98...\xe2\x80\x99 )将被替换为其标准输出,并删除所有尾随换行符。如果替换未用双引号括起来,则使用 IFS 参数将输出分解为单词。替换$(cat foo)可能会被等效但更快的替换$(<foo)。无论哪种情况,如果设置了 GLOB_SUBST 选项,则输出适合生成文件名。
请注意,问题中的示例#2 会导致 NULL 的无限回显,原因是:
\n\n\n\n\n如果替换未用双引号括起来,则使用 IFS 参数将输出分解为单词。
\n
换句话说,shell 无限地等待echo,因为默认分隔符是 SPACE,所以 echo 永远不会完成。 请参阅 TLDP:内部变量。这为命令留下了一个挂起的管道cat。
直觉上,我相信 4 和 5 是由于输出重定向而起作用的。
\n| 归档时间: |
|
| 查看次数: |
1949 次 |
| 最近记录: |