原因是xargs设置stdin为/dev/null,而vim需要stdin设置为/dev/tty。
BSD xargs(例如Mac)解决方案:
echo -e 'file1\nfile2' | xargs -o vim
-o将stdinxarg的子进程(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使用了stdinVim不能使用的虚拟道具,并打破了之后的一切。