`grep -l .. | xargs vim` generates a warning, why?
Solution 1
Because Vim is invoked from inside the pipeline, the stdin
is connected to the previous pipeline's output, not the terminal. As an interactive command, Vim needs to receive its input from the terminal.
Better avoid the pipe, e.g. via
$ vim $(grep -rl test .)
or from inside Vim:
:args `grep -rl test .`
Solution 2
Vim needs its standard input to be the terminal where you'll enter commands, but it gets either /dev/null
or the pipe from grep
depending on your xargs
implementation.
You can restore standard input through an intermediate shell.
grep -rl test . | xargs sh -c 'vim -- "$@" <$0' /dev/tty
If the file names don't contain any whitespace character or any of \[?*
, you can use command substitution instead:
vim $(grep -rl test .)
One way to cope with special characters (other than newline) is to restrict word splitting to newlines and turn off globbing.
(IFS='
'; set -f; exec vim $(grep -rl test .))
Solution 3
If you use GNU Parallel instead of xargs you do not get the warning and your terminal settings are not changed afterwards:
grep -rl test . | parallel -X --tty vi
Added bonus: It works even if filenames contain space, ' or ".
Related videos on Youtube
dan
Updated on September 18, 2022Comments
-
dan over 1 year
If I run a command like
grep -rl test . | xargs vim
I get a warning "Vim: Warning: Input is not from a terminal." But I am still able to edit the files. Why the warning?
-
lgeorget almost 11 yearsRelated question: superuser.com/questions/336016/…
-
kenorb about 9 yearsUse:
vim $(grep -rl test .)
instead. -
kenorb about 9 yearsRelated: Terminal borked after invoking Vim with xargs at Vim SE
-
-
lgeorget almost 11 yearsIn this case, xargs' stdin is the pipeline, not vim's stdin.
-
lgeorget almost 11 yearsvim's stdin is /dev/null if invoked with xargs.
-
Stéphane Chazelas almost 11 years@lgeorget, that is not true of all
xargs
implementations. Solaris', and Busybox' at least don't (the spawned processes inherit the stdin of xargs, that is the pipe). That's not a POSIX requirement. -
lgeorget almost 11 years@StephaneChazelas Ok, it's worth knowing that. Thank you for the information!