Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This question already has an answer here:

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?

share|improve this question

marked as duplicate by Anthon, cuonglm, slm Feb 14 at 15:03

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Related question: superuser.com/questions/336016/… –  lgeorget May 28 '13 at 13:39
    
Use: vim $(grep -rl test .) instead. –  kenorb Feb 18 at 11:15
    
Related: Terminal borked after invoking Vim with xargs at Vim SE –  kenorb Feb 19 at 15:20

3 Answers 3

up vote 9 down vote accepted

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 .`
share|improve this answer
1  
In this case, xargs' stdin is the pipeline, not vim's stdin. –  lgeorget May 28 '13 at 13:29
3  
vim's stdin is /dev/null if invoked with xargs. –  lgeorget May 28 '13 at 13:38
3  
@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. –  Stéphane Chazelas May 28 '13 at 14:46
    
@StephaneChazelas Ok, it's worth knowing that. Thank you for the information! –  lgeorget May 28 '13 at 14:58

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 .))
share|improve this answer

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 ".

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.