Edward Ned Harvey
Edward Ned Harvey

Reputation: 7031

With python sh module, how to preserve combined stdout and stderr?

Using the python sh module (http://amoffat.github.io/sh/index.html), how can I get the combined stdout and stderr, just like it would be if I had run the command on the terminal?

Upvotes: 1

Views: 2552

Answers (3)

Hi-Angel
Hi-Angel

Reputation: 5639

…just like it would be if I had run the command on the terminal?

Though _err_to_out was mentioned, but it has to be passed to every command, which is inconvenient if you want opt-out behavior.

Having studied the code, I found it's possible to achieve the "opt-out" behavior you'd expect from a command running in terminal by modifying sh.Command._call_args dictionary.

Example:

import sh

sh.Command._call_args['err_to_out'] = True # redirect stderr → stdout
sh.Command._call_args['out']        = True # print stdout by default

sh.echo('Hello World!')
try:
    sh.ls("non existing dir")
except: # don't print stacktrace for demo purposes
    pass

Output:

λ python3 test.py
Hello World!
/usr/bin/ls: cannot access 'non existing dir': No such file or directory

If you want then to store the output to a variable, it may be done by passing _tee keyword param, e.g.: myvar = sh.echo('hello', _tee='out')

Upvotes: 0

Steve
Steve

Reputation: 1

You can also use _fg=True, for example

import sh

sh.ls("/", _fg=True)

Output:

/usr/bin/python3.6 /home/steve/test.py
bin
boot
dev
etc
home
initrd.img
initrd.img.old
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
vmlinuz
vmlinuz.old

Upvotes: -1

DrM
DrM

Reputation: 2525

Here is an example redirecting stdout and stderr from sh.ls(), to the process stdout and stderr.

import sh
import sys

sh.ls(_out=sys.stdout, _err=sys.stderr)

Stdout can also be captured into a string, per the following

import sh
import sys

s = sh.ls()
print( s )

You can also use:

sh.ls(_err_to_out = True)

Upvotes: 4

Related Questions