1

I am using a software that my lab has developed, lets call it cool_software. When I type cool_software on terminal, basically I get a new prompt cool_software > and I can imput commands to this software from the terminal.

Now I would like to automate this in Python, however I am not sure how to pass the cool_software commands onto it. Here's my MWE:

import os
os.system(`cool_software`)           
os.system(`command_for_cool_software`)

The problem with the code above is that command_for_cool_software is executed in the usual unix shell, it is not executed by the cool_software.

7
  • 1
    Use pexpect Commented Sep 28, 2021 at 22:54
  • 1
    Or use subprocess.Popen() and then write command_for_cool_software to the stdin pipe. Commented Sep 28, 2021 at 22:54
  • @Barmar Thank you!! I am very interested in the subprocess solution. How would it look like? Commented Sep 28, 2021 at 22:55
  • @Barmar perhaps subprocess.Popen(["cool_software"], stdin="command_for_cool_software") Commented Sep 28, 2021 at 22:59
  • 1
    If that's the only input, that would work. Commented Sep 28, 2021 at 23:01

1 Answer 1

2

Based on @Barmar suggestion from the comments, using pexpect is pretty neat. From the documentation:

The spawn class is the more powerful interface to the Pexpect system. You can use this to spawn a child program then interact with it by sending input and expecting responses (waiting for patterns in the child’s output).

This is a working example using the python prompt as an example:

import pexpect

child = pexpect.spawn("python") # mimcs running $python
child.sendline('print("hello")') # >>> print("hello")
child.expect("hello") # expects hello
print(child.after) # prints "hello"
child.close()

In your case, it will be like this:

import pexpect

child = pexpect.spawn("cool_software")
child.sendline(command_for_cool_software)
child.expect(expected_output) # catch the expected output
print(child.after)
child.close()

NOTE

child.expect() matches only what you expect. If you don't expect anything and want to get all the output since you started spawn, then you can use child.expect('.+') which would match everything.

This is what I got:

b'Python 3.8.10 (default, Jun  2 2021, 10:49:15) \r\n[GCC 9.4.0] on linux\r\nType "help", "copyright", "credits" or "license" for more information.\r\n>>> print("hello")\r\nhello\r\n>>> '
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you!! Would expected output be the name of the output?
From the documentation: The spawn class is the more powerful interface to the Pexpect system. You can use this to spawn a child program then interact with it by sending input and expecting responses (waiting for patterns in the child’s output).
@Euler_Salter, sorry I misread your question. I thought you were asking about what expect() does. Regarding to your question, I edited my answer. Hope this helps

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.