Search code examples
shellvimshellexecute

Best way to read output of shell command


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?


Solution

  • 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)