Dun*_*eal 4 bash vim io-redirection
我有以下简单命令:
$ echo <(vipe)
Run Code Online (Sandbox Code Playgroud)
我希望它打开一个 vim 缓冲区,我可以对其进行编辑,然后当我完成后,回显分配用于保存 vim 缓冲区内容的临时文件的名称。
相反,vim 缓冲区的行为非常奇怪,不响应某些按键,最终 vim 完全崩溃。
我的哪个假设是错误的?
首先,让我们看看在终端中看到的内容:
\n\n$ echo <(vim)\n/dev/fd/63\n$ Vim: Warning: Output is not to a terminal\n
Run Code Online (Sandbox Code Playgroud)\n\n请注意,您会立即收到提示,而无需等待编辑器终止。进程替换不会等待命令完成,它会在命令和 shell 之间创建一个管道。该管道的名称被传递给进程替换作为其参数的命令,此处echo
打印出该名称并立即返回,之后 bash 关闭该管道。
Vim 仍在运行,其标准输入和标准错误连接到终端,但未连接其标准输出。因此,Vim 正在获取输入并发出一些错误消息,但其大部分显示都转到标准输出,这是一个损坏的管道。
\n\nbash 和 vim 都从终端读取。这会导致您的击键在一定程度上随机地发送给其中一个或另一个。这种情况通常不会发生,因为后台进程被禁止从终端读取\xe2\x80\x94\xc2\xa0 如果他们尝试这样做,那么他们会收到 SIGTTIN 信号,如果他们忽略该信号,那么他们的read
调用就会返回一个错误。但在这种情况下,vim
作为前台进程组的一部分执行,因为进程替换不会创建新的进程组,因此它可以从终端读取并捕获一些击键。
在某个时刻,Vim 决定无法再忍受并退出。我不知道是什么让它做出这样的决定。
\n\n进程替换不会创建临时文件,而是创建管道,因此您的方法没有意义。Zsh有一个进程替换结构,它确实创建了一个临时文件 ( =(somecommand)
),但这也不起作用:您可以运行echo =(vipe </dev/null)
,这将打印出临时文件的名称,该文件在打印时刚刚包含已被删除。
要做你想做的事,你需要自己处理临时文件的删除。我不认为有任何 shell 结构可以帮助你。调用mktemp
创建临时文件,然后按普通方式编辑即可。
tmpfile=$(mktemp)\n"${VISUAL:-"${EDITOR:-vi}"}" "$tmpfile"\necho "$tmpfile"\n\xe2\x80\xa6\nrm "$tmpfile"\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
426 次 |
最近记录: |