2

I'm trying to run a sequence of shell commands in the same environment:

same exported variables, persistent history, etc.

And I want to work with each commands output before running the next command.

After looking over python subprocess.run and Pexpect.spawn neither seem to provide both features.

subprocess.run allows me to run one command and then examine the output, but not to keep the environment open for another command.

Pexpect.spawn("bash") allows me to run multiple commands in the same environment, but i can't get the output until EOF; when bash itself exits.

Ideally i would like an interface that can do both:

shell = bash.new()

shell.run("export VAR=2")

shell.run("whoami")
print(shell.exit_code, shell.stdout())
# 0, User

shell.run("echo $VAR")
print(shell.stdout())
# 2

shell.run("!!")
print(shell.stdout())
# 2

shell.run("cat file -")
shell.stdin("Foo Bar")
print(shell.stdout())
# Foo Bar
print(shell.stderr())
# cat: file: No such file or directory

shell.close()
Dylan .B
  • 31
  • 3
  • @tripleee This question has nothing to do with output buffering, If i were to use Popen this becomes a question about input, a topic not mentioned in the linked post. I don't think this is a duplicate. – Dylan .B Jun 02 '19 at 14:52
  • I have removed the duplicate, but those are the kinds of things you are up against. See the other interactive subprocess questions in the [`subprocess` tag info page.](/tags/subprocess/info) – tripleee Jun 02 '19 at 15:17

1 Answers1

0

Sounds like a case for Popen. You can specify bufsize to disable buffering, if it gets in the way.

Example from the linked page:

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

There's also proc.stdin for sending more commands, and proc.stderr.

Roland Weber
  • 3,395
  • 12
  • 26
  • Popen doesn't seem to allow for communication how i would like ```python shell.run("cat file -") shell.stdin("Foo Bar") ``` There appears to be only one method for both writing and reading. – Dylan .B Jun 02 '19 at 14:31
  • @Dylan.B Popen creates pipes to stdin, stdout and stderr of the process you start. How else do you want to communicate? – Roland Weber Jun 02 '19 at 14:33
  • 1
    Things like `print(shell.exit_code)` are impossible because i only have a hook to the shell, plus `bufsize` changes how Popen communicates with the shell, not how programs communicates with the shell, leaving many buffering issues. – Dylan .B Jun 02 '19 at 14:49
  • Execute `echo $?` to get the exit code of the previous command printed to stdout. – Roland Weber Jun 07 '19 at 17:08