19

When I do "locate 50local.policy | xargs vim", I get the error "Vim: Warnung: Die Eingabe kommt nicht von einem Terminal" (translation: Vim: Warning: The input does not come from a terminal).

I can edit successfully with vim but after I close it my terminal behaves strangely (I can't type letters and when I hit enter the shell prompt simply gets repeated. When I do it with "xargs gedit" it does not create those problems.

I use Ubuntu 11.10 with Gnome 3 and Gnome-Terminal 3.0.1.

Konrad Höffner
  • 11,100
  • 16
  • 60
  • 118

3 Answers3

33

Vim expects to be connected to a real terminal and sends codes appropriate to that.

Reset the terminal with

reset

The easiest workaround:

locate 50local.policy | xargs gvim

Rationale gui vim doesn't require a terminal

Otherwise:

vim $(locate 50local.policy)

Rationale vim is started directly connected to the terminal (instead of as a child process under xargs which in turn runs in a subshell with stdin/stdout connected to pipes instead of a terminal). It is like saying

vim /usr/some/dir/50local.policy /usr/local/some/dir/50local.policy

Alternatively

You can dodge the issue by not starting vim with the arguments, but adding the arguments from vim! Vim is in fact a lot better at running shells than shells are at running vim.

Whilst in vim:

:args `locate 50local.policy`
:rewind

This sets the argument list to the files returned from the shell command between the ticks; :rewind then goes to the first file from that list. If you were editing multiple matches, try this:

:w|next

This sequence of commands (separated by |) writes the current buffer to file, then goes to the next file in the args list.

jamessan
  • 41,569
  • 8
  • 85
  • 85
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Just curious: what's the difference between `vim $(...)` and what the OP is doing? – sidyll Nov 22 '11 at 15:04
  • @sidyll Added rationales in-post – sehe Nov 22 '11 at 16:41
  • 2
    @sidyll The OP is using `xargs` to create the `vim` process, while in the other case, the process is created from the shell. – Philippe Nov 22 '11 at 16:43
  • Thanks sehe and @Philippe . Actually I never thought `xargs` would execute the command by itself… – sidyll Nov 22 '11 at 17:46
  • 2
    @sidyll The point is that xargs executes it _with stdin/out not connected to a terminal_ (doing `echo hello | vim -` has the same issues). – sehe Nov 22 '11 at 18:13
  • 1
    @eMPee584 thanks for a helpful edit. I can't upvote it, but I would :) – sehe Apr 15 '13 at 17:14
6

An other alternative is to execute xargs with the -o option. From the man page:

-o      Reopen stdin as /dev/tty in the child process before executing
        the command.  This is useful if you want xargs to run an interac-
        tive application.

Note, -o is a BSD extension to xargs.

A more portable means to achieve the same effect is:

xargs sh -c 'vim "$@" < /dev/tty' vim
jamessan
  • 41,569
  • 8
  • 85
  • 85
mkomitee
  • 760
  • 6
  • 10
2

While 'reset' fixes the problem, you can also explicitely re-activate the echo behaviour with:

stty echo