trouble with `_out` vs _fg`
redthing1 opened this issue · comments
Hello,
So I have been working with ab-av1
which is a video encoder that draws a progress bar (in the standard form of writing to stderr with \r
)
So _fg
is great for synchronously running the command and also keeping the progress bar.
And when I need to pass some more options, _out=sys.stdout, _err=sys.stderr
works too, and preserves the progress bar.
But when I want to capture outputs AND run synchronously, I cannot find a way to do this.
There's _tee
referenced here which lets me both pipe stderr AND capture it to a variable, but I cannot find a way to make this work that preserves the progress bars.
I'm running ab-av1 crf-search -i somevideo.mp4
Any idea how I could do all of the following at once:
- capture outputs
- run synchronously
- keep progress bars working
You probably want to look into _tty_in
and _tty_out
. Many programs change their behavior based on whether or not they think they're connected to a tty. I suspect fiddling with those will get you the progress bar back.
First of all, this is one of my favorite libraries and I appreciate the rapid response.
I'm doing my best to run the command in the foreground but also capture stderr.
running_encode_cmd = encode_cmd(_err=sys.stderr)
This does run it in the foreground and shows progress bars, but it returns an empty stdout and stderr to the sh.ErrorReturnCode
I want this foreground execution and capturing the output.
I found _tee
for this:
running_encode_cmd = encode_cmd(_tee="err")
This does return the output but doesn't print it live to the foreground.
Any hints on this?
Sorry, I misunderstood.
Try encode_cmd(_out=sys.stdout, _err_to_out=True, _tee="out")
_out=sys.stdout
sends the output to your terminal_err_to_out=True
sends the stderr to the same place that stdout is going_tee="out"
sends stdout (which also contains stderr, thanks to_err_to_out
) to be returned as well as sent to the stdout handler (in this casesys.stdout
)
That should print stderr + stdout to the terminal, while also returning it.
Alternatively there is a way to do this with iteration, iterating line by line over the command that you're running, allowing you to save the output and print it if you want to. A long-running encoding command seems more suited towards this. Check out _iter
if you're interested. You'll also need to use _err_to_out
to get at the stderr as well though.
Thank you!
This appears to work:
for line in encode_cmd(_iter=True, _err_to_out=True, _out_bufsize=0):
# write it to stdout
if isinstance(line, bytes):
sys.stdout.buffer.write(line)
else:
sys.stdout.write(line)