9

In Vim, What is the best (portable and fast) way to read output of a shell command? This output may be binary and thus contain nulls and (not) have trailing newline which matters. Current solutions I see:

  1. Use system(). Problems: does not work with NULLs.
  2. Use :read !. Problems: won’t save trailing newline, tries to be smart detecting output format (dos/unix/mac).
  3. Use ! with redirection to temporary file, then readfile(, "b") to read it. Problems: two calls for fs, shellredir option also redirects stderr by default and it should be less portable ('shellredir' is mentioned here because it is likely to be set to a valid value).
  4. Use system() and filter outputs through xxd. Problems: very slow, least portable (no equivalent of 'shellredir' for pipes).

Any other ideas?

Gabe
  • 79,868
  • 10
  • 131
  • 226
ZyX
  • 49,123
  • 7
  • 101
  • 128

1 Answers1

5

You are using a text editor. If you care about NULs, trailing EOLs and (possibly) conflicting encodings, you need to use a hex editor anyway?

If I need this amount of control of my operations, I use the xxd route indeed, with

:se binary

One nice option you seem to miss is insert mode expression register insertion:

C-r=system('ls -l')Enter

This may or may not be smarter/less intrusive about character encoding business, but you could try it if it is important enough for you.

Or you could use Perl or Python support to effectively use popen

Rough idea:

:perl open(F, "ls /tmp/ |"); my @lines = (<F>); $curbuf->Append(0, @lines)
sehe
  • 328,274
  • 43
  • 416
  • 565
  • You can try `=system('printf ''\x00''')`. It won’t output anything, while `:%!printf '\x00'` will put single NULL viewed as `^@` in the buffer (big problem: `:%!printf '\x00\r\n'` does the same). – ZyX Feb 08 '12 at 04:01
  • Problem here is that I do not want to have two functions: “read command into buffer”, normally achievable by “%!” and “put command output into file” and I can’t say I won’t ever need more. Analog to `readfile()` is the most flexible solution in this case. – ZyX Feb 08 '12 at 04:09
  • Just thought of using perl/python support; see answer for starter – sehe Feb 08 '12 at 08:22