原因是xargs
设置stdin
为/dev/null
,而vim
需要stdin
设置为/dev/tty
。
BSD xargs
(例如Mac)解决方案:
echo -e 'file1\nfile2' | xargs -o vim
-o
将stdin
xarg的子进程(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' $0 $1 $2 etc
。
"$@"
扩展为位置参数"$1", "$2"
等。它不包含“ $ 0”,因为这是脚本名称的特殊参数,而不是位置参数。这就是为什么我们需要添加虚拟字符串zero
(可以是任何字符串)代替的原因$0
。否则,您将丢失第一个文件。
因此,扩展之后"$@"
,您将得到:
bash -c '</dev/tty vim file1 file2'
3. bash -c
将执行COMMAND_STRING:
</dev/tty vim file1 file2
</dev/tty
设置为stdin
,/dev/tty
以便vim
可以在交互模式下工作。
xargs
使用了stdin
Vim不能使用的虚拟道具,并打破了之后的一切。