xargs
调用Vim,就像这样:find . -name '*.java' | xargs vim
…哪种工作方式: />当Vim启动时,我会短暂看到以下警告闪烁:
Vim: Warning: Input is not from a terminal
编辑工作—
:files
正确枚举了所有.java
文件我可以保存并退出。
但是,退出Vim后,我的终端坏了:提示没有回显。
根本没有出现回车,并且有时仅出现换行。
直到我发出
reset(1)
命令重新初始化终端为止。这是Vim的错误,还是有一个更令人满意的解释,为什么它会与终端交互?我已经看到它发生在Linux和各种Unices上的7.3版(似乎无关紧要)的Vim上。
我知道一种解决方法,即
vim $(find . -name '*.java')
。其他解决方法也将受到欢迎,尽管这不是我的主要问题。#1 楼
在调用vim并将其连接到前一个管道的输出而不是终端时,会发生这种情况,而不是接收到意外的输入(例如NUL)。运行时也会发生同样的情况:
vim < /dev/null
,因此reset
命令在这种情况下会有所帮助。 如果使用
find
传递文件名进行编辑,则不需要xargs
,而只需使用-exec
即可,例如:find . -name '*.java' -exec vim {} +
如果要使用
xargs
,则在Unix / macOS上应使用-o
参数,例如:find . -name '*.java' | xargs -o vim
-o
在执行命令之前,在子进程中以/ dev / tty重新打开stdin。如果希望xargs运行交互式应用程序,这将很有用。或:
find . -name "*.java" -type f -print0 | xargs -o -0 vim
注意:使用
-print0
/ -0
将支持带空格的文件名。find
+ BSD xargs
在Unix / macOS上,您可以尝试以下解决方法:
find . -name '*.java' | xargs -J% sh -c 'vim < /dev/tty $@'
还可以使用命令替换语法,例如:
vim $(find . -name '*.java')
vim `find . -name '*.java`
GNU
parallel
而不是xargs
来强制进行tty分配,例如:find . -name '*.java' | parallel -X --tty vi
注意:Unix / OSX上的
parallel
无法工作,因为它具有不同的参数,并且不起作用。 t支持tty。许多其他流行的命令也提供伪tty分配(例如
-t
中的ssh
),因此请寻求帮助。其他建议是使用:
ex
命令行编辑器可解析数据或使用Ex模式,有关更多详细信息,请参见:如何编辑文件n互动式(例如在管道中)?
vipe
(Vim命令管道)使用以下简单脚本:
#!/bin/sh
# usage: find ... | vip
exec vim < /dev/tty "$@"
相关信息:
错误GH-982:vim无法处理将STDIN设置为/ dev / null。
通过find调用vi | xargs破坏了我的终端。为什么?在超级用户SE
命令行中通过Vim exec命令和Vim:警告:输入不是来自stackoverflow上的终端
试图“定位”并在以下位置打开文件unix SE
less.vim在askubuntu SE上的Ubuntu 12.04 lts上不起作用
grep -l .. | xargs vim
生成警告,为什么? unix SE上的[dup] Vim输入不是来自终端的输入。 ,文件还是目录中的所有文件?评论
我的GNU xargs没有-J。这似乎是GNU版本中不存在的MacOS(BSD)选项。
–丹尼斯·威廉姆森
18年2月2日在21:34
#2 楼
解决方法建议:将缓冲区用作文件系统导航器使用
vim -
命令从stdin读取路径列表。 Vim的:help --
对此进行了解释:1 开始编辑一个新的缓冲区,其中充满了从stdin读取的文本。现在通常从stdin中读取的命令将
从stderr中读取。示例:
find . -name "*.c" -print | vim -
然后可以使用gf或Ctrl-wCtrl-f分别导航到同一缓冲区中或新拆分窗口中的文件。
解决方法:参数列表
另一种很棒的方法是使用Vim的参数列表。
:argadd **/*.java
命令将递归地使用在当前目录内找到的所有Java文件填充Vim的参数列表。然后,您可以使用:next
和:prev
在文件之间移动。1第一个
-
告诉Vim您要搜索命令行选项的帮助,第二个实际上是命令行标记您要搜索的。阅读:help help-context
了解更多类似这样的技巧。#3 楼
除了reset
之外,您还可以尝试:stty sane
,这也将使您的终端再次可用。
以某种方式可以认为这是Vim的不当行为,至少Neovim目前没有此问题。
评论
这不能完全回答问题,但可以帮助我,所以+1。
–恢复莫妮卡-notmaynard
16-10-18在16:16
这确实回答了我的问题;)尽管在阅读了更多的OP之后,我想也应该进行重置。
– Sridhar Sarnobat
19年6月20日在17:47
#4 楼
原因是xargs
将stdin
设置为/dev/null
,而vim
需要stdin
为/dev/tty
。BSD
xargs
(例如Mac)解决方案:echo -e 'file1\nfile2' | xargs -o vim
-o
将xarg的子进程的stdin
(在本例中为vim
)设置为dev/tty
。GNU
xargs
(例如Linux)解决方案:GNU
xargs
没有-o
选项。相反,您将不得不使用更复杂的解决方法。 (注意:保留尾随的zero
字符串非常重要,请不要忘记它。)echo -e 'file1\nfile2' | xargs bash -c '</dev/tty vim "$@"' zero
还可以将其命名为别名:
alias vimin='xargs bash -c '\''</dev/tty vim "$@"'\'' zero'
echo -e 'file1\nfile2' | vimin
GNU xargs解决方案的详细说明
让我们逐步分解它:
echo -e 'file1\nfile2' | xargs bash -c '</dev/tty vim "$@"' zero
1。
xargs
只是将stdin
附加到字符串的末尾,因此xargs
将执行以下操作: bash -c '</dev/tty vim "$@"' zero file1 file2
2。
bash -c
的格式为bash -c 'COMMAND_STRING' "$@"
etc
。"", ""
扩展为位置参数zero
等。它不包含“ $ 0”,因为这是脚本名称的特殊参数,而不是位置参数。这就是为什么我们需要添加虚拟字符串"$@"
(可以是任何字符串)代替bash -c
的原因。否则,您将丢失第一个文件。因此,在扩展
</dev/tty
之后,您将得到: bash -c '</dev/tty vim file1 file2'
3。
stdin
将执行COMMAND_STRING: </dev/tty vim file1 file2
/dev/tty
将vim
设置为q4312079q,以便q4312079q可在交互模式下工作。评论
+1这似乎是票数最高的答案的重复,但事实并非如此。 $ 0占位符(此处为“零”)是关键。
–丹尼斯·威廉姆森
18年11月2日在21:36
#5 楼
我发现缺少所有这些答案。解决了xargs问题之后,对我来说,最简单的方法-在通用框上进行以下搜索和打开操作:vim -O `grep -lir mySearchTerm *`
我将
find
与xargs
和grep
结合使用没有问题,但是我发现语法令人讨厌。作为一个日常编码员,使用vim
和终端作为他们的IDE,并不断在文件中搜索属性,这就是我一直在使用的东西。find . -path ./node_modules -prune -o -name '*.js' | xargs grep -i mySearchTerm
有一个时间和地点,同时打开文件通过vim和其他方法。对我来说,这很少。希望对别人有帮助。
评论
FWIW建议不要使用旧的反引号,而应使用$(...)。它在命令行中不如在脚本中那么重要,但我认为最好在答案中使用它:)(此处和此处的引用)
–statox♦
19-10-11在8:04
评论
我有点希望您填写尽可能多的问题,但是……这个问题多年来在SO / SU和其他地方已经被回答了数十次:xargs使用了一个虚拟的stdin,Vim无法使用然后破坏一切。@romainl我在那些网站上并不活跃,而且我从未见过它问过这个问题-老实。
相关:superuser.com/questions/336016/…-也许有人可以将最重要的答案浓缩为一个好答案。
很好的问题-这件事在我身上无数次发生。另外,我不使用任何其他SO网站-如果它与vim有关,我想在这里找到它。