I have a Python script that needs to interact with the user via the command line, while logging whatever is output.
I currently have this:
# lots of code
popen = subprocess.Popen(
args,
shell=True,
stdin=sys.stdin,
stdout=sys.stdout,
stderr=sys.stdout,
executable='/bin/bash')
popen.communicate()
# more code
This executes a shell command (e.g. adduser newuser02) just as it would when typing it into a terminal, including interactive behavior. This is good.
Now, I want to log, from within the Python script, everything that appears on the screen. But I can't seem to make that part work.
I've tried various ways of using subprocess.PIPE, but this usually messes up the interactivity, like not outputting prompt strings.
I've also tried various ways to directly change the behavior of sys.stdout, but as subprocess writes to sys.stdout.fileno() directly, this was all to no avail.
shell=True? Especially when the thing you're launching is itself/bin/bash? You're basically telling Python to start a copy ofbashto tell it to start another copy ofbashto (presumably, since you didn't show the whole code) tell it to start a copy ofadduser. You probably don't need even one shell involved, but I can't imagine why you'd need two.executabledoesn't start a newbashprocess: it tellssubprocessmodule to use its value instead of/bin/shifshell=True.argsis presumably some shell command with bash-isms such as'use_tty &>/dev/null'. As I understand the intent is:script -c '/bin/bash -c "$args"' log. Though as my answer shows, you don't necessarily need even one additional bash process to run a command here.