-1

I run the following command in the terminal.

sh -c "echo out; echo err 2>&1" >>(tee -a stdout.log) 2>>(tee -a stdout.log >&2)

output:

out  
err

Using os.system in Python will report an error.

import os
cmd = """
sh -c "echo out; echo err 2>&1" > >(tee -a stdout.log) 2> >(tee -a stdout.log >&2)
"""
os.system(cmd)
sh: -c: line 1: syntax error near unexpected token `>'
sh: -c: line 1: `sh -c "echo out" > >(tee -a stdout.log) 2> >(tee -a stdout.log >&2)'
zcfh
  • 101
  • 1
  • 9
  • 2
    Why did you use a different command string in Python than you used in the terminal? – mkrieger1 Jan 07 '21 at 02:40
  • It is quite risky (i.e. undefined behaviour) to use the same file, `stdout.log`, for both `tee` statements. It may work sometimes, but it may also break . – user1934428 Jan 07 '21 at 07:59
  • 2
    We have two processes appending to the same file simultaneously. Even if `tee` writes to its file unbuffered, there is no guarantee that the two `tee` won't try to write at the same time. The safe way to do it would be IMO to do a `2>&1 | tee -a stdout.log`. – user1934428 Jan 07 '21 at 08:12
  • For other reasons, I don't want stderr> stdout.@user1934428 – zcfh Jan 07 '21 at 09:20

1 Answers1

1

>(...) is bash-specific syntax. Make that bash -c instead of sh -c.

Also you should enclose the entire command in quotes since -c expects a single argument.

cmd = """
bash -c 'echo out > >(tee -a stdout.log) 2> >(tee -a stdout.log >&2)'
"""

To test writing to both stdout and stderr like your original example, try like this with curly braces:

cmd = """
bash -c '{ echo out; echo err 2>&1; } > >(tee -a stdout.log) 2> >(tee -a stdout.log >&2)'
"""
John Kugelman
  • 349,597
  • 67
  • 533
  • 578