调用vim
through 时find | xargs
,像这样:
find . -name "*.txt" | xargs vim
Run Code Online (Sandbox Code Playgroud)
你会收到一个警告
Input is not from a terminal
Run Code Online (Sandbox Code Playgroud)
以及之后的行为非常糟糕的终端。为什么?
这个问题明确地是关于为什么,而不是关于如何避免。这是在别处被问到并回答的。
Jam*_*gan 165
(从grawity的解释继,这xargs
点stdin
到/dev/null
。)
这个问题的解决方案是将-o
参数添加到xargs
. 来自man xargs
:
-o
/dev/tty
在执行命令之前 像在子进程中一样重新打开 stdin 。如果您想xargs
运行交互式应用程序,这很有用。
因此,以下代码行应该适合您:
找 。-name "*.txt" | xargs -o vim
GNU xargs 从 2017 年的某个版本开始支持此扩展(带有长选项名称--open-tty
)。
对于旧版本或其他版本的xargs,可以显式传入/dev/tty
解决问题:
find . -name "*.txt" | xargs bash -c '</dev/tty vim "$@"' ignoreme
Run Code Online (Sandbox Code Playgroud)
(在ignoreme
那里占用 $0,所以 $@ 是来自 xargs 的所有参数。)
use*_*686 108
当您通过 调用程序时xargs
,程序的 stdin(标准输入)指向/dev/null
。(因为 xargs 不知道原始的标准输入,它做了次好的事情。)
$ 真 | xargs filan -s 0 chrdev/dev/null 1 tty /dev/pts/1 2 tty /dev/pts/1 $ 真 | xargs ls -l /dev/fd/
Vim 期望其 stdin 与其控制终端相同,并直接在 stdin 上执行各种与终端相关的ioctl。当在/dev/null
(或任何非 tty 文件描述符)上完成时,这些 ioctl 毫无意义并返回 ENOTTY,它被默默地忽略。
我对一个更具体的原因的猜测:在启动时 Vim 读取并记住旧的终端设置,并在退出时恢复它们。在我们的情况下,当为非 tty fd(文件描述符)请求“旧设置”时,Vim 接收所有值为空且禁用所有选项,并粗心地将其设置为您的终端。
您可以通过运行vim < /dev/null
,退出它,然后运行来看到这一点stty
,这将输出大量的<undef>
s。在 Linux 上,运行stty sane
将使终端再次可用(尽管它会丢失诸如 之类的选项iutf8
,以后可能会引起一些小麻烦)。
您可以认为这是 Vim 中的一个错误,因为它可以打开/dev/tty
以进行终端控制,但不能。(在启动过程中的某个时刻,Vim 将它的 stderr 复制到 stdin,这允许它读取你的输入命令——从一个为写入而打开的 fd——但即使这样也做得不够早。)
小智 34
最简单的方法:
vim $(find . -name "*foo*")
Run Code Online (Sandbox Code Playgroud)
小智 22
如果您在 find 上使用 -exec 选项而不是管道到 xargs,它应该可以正常工作。
find . -type f -name filename.txt -exec vi {} +
Run Code Online (Sandbox Code Playgroud)
Ole*_*nge 10
改用 GNU Parallel:
find . -name "*.txt" | parallel -j1 --tty vim
Run Code Online (Sandbox Code Playgroud)
或者,如果您想一次性打开所有文件:
find . -name "*.txt" | parallel -Xj1 --tty vim
Run Code Online (Sandbox Code Playgroud)
它甚至可以正确处理如下文件名:
My brother's 12" records.txt
Run Code Online (Sandbox Code Playgroud)
观看介绍视频以了解更多信息:http : //www.youtube.com/watch?v=OpaiGYxkSuQ
归档时间: |
|
查看次数: |
25846 次 |
最近记录: |