5

If I run

(setq some-variable (shell-command-to-string some-command))

...and the execution of the command in some-command results in some output sent to stderr, this stderr output ends up in some-variable.

How can I discard the stderr output, so that the result consists exclusively of the output sent to stdout? (Better yet would be to capture the stdout and stderr outputs in separate variables.)

Note that it is not enough to add something like 2>/dev/null to the command in some-command, because the stderr output may come from a shell initialization file (e.g. .bashrc), and thus would not be captured by the 2>/dev/null redirection.

2
  • Not really sure about that, but, what about defining setting the shell-command-default-error-buffer variable?
    – Nsukami _
    Apr 4, 2016 at 17:27
  • @Nsukami_: this variable apparently applies only to shell-command and shell-command-on-region... At any rate, I have not been able to come up with a setting for it that produces a different behavior from the default one.
    – kjo
    Apr 4, 2016 at 18:42

1 Answer 1

5

Use the following form instead of (shell-command-to-string some-command):

(with-output-to-string
    (with-current-buffer
      standard-output
      (process-file shell-file-name nil '(t nil)  nil shell-command-switch some-command)))

That is essentially what shell-command-to-string does with the only change that it does discard stderr.

You can also substitute the nil in '(t nil) for some file name to re-direct stderr into that file.

3
  • Thanks! (I had tried an incorrect version of this, where I mistakenly used '(t . nil) instead of '(t nil), who knows where I got that from; unfortunately, the resulting function just worked like before, which gave me no clue as to what I had done wrong.)
    – kjo
    Apr 5, 2016 at 13:22
  • 1
    BTW, I tried the second form you mention at the end, but I see nothing in the buffer designated for the stderr output (the stdout output remains as it should be, though). More specifically, I tried replacing the argument '(t nil) with '(t "*STDERR*"), and bound some-command to something like "wc -l /dev/null nonexistent", which should result in output being sent to both stdout and stderr. I tried many variants (e.g. with the *STDERR* buffer already open, etc.), but I never saw any output in the designated stderr buffer. Did you have something else in mind?
    – kjo
    Apr 5, 2016 at 13:22
  • @kjo I've corrected my answer according to your comment. The error output goes not to a buffer but to a file. This is described in the help of call-process. Thanks for you comment (+1).
    – Tobias
    Apr 5, 2016 at 13:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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