If I had a interactive program or shell like bash
, how do I automate and script what I want to do with Python?
There’s a useful pip module called pexpect
that you can install.
The idea of pexpect
originated from a programming language called Expect
that automates interactions with programs that expose a text terminal like ftp
, ssh
, etc.
Think of any program that opens a session that you have to exit
!
Prerequisites
- Python 2.7 or Python 3.3 or above
pip install pexpect
- If you get lost, read the documentation.
Now, that you have installed pexpect
, we can make a simple program as an example.
bash example. Sending one command.
Let’s say that I wanted to automate a new session of bash
and use ls
.
bash
works a little differently than other interactive programs since it has a flag that allows input.
1 2 3 4 5 6 7 8 9 10 11 12 | import pexpect # The child process can be any interactive program. # /bin/bash is an example of an interactive menu. You spawn the interactive window. child = pexpect.spawn("/bin/bash -c ls") # You use the expect function to write what output you expect. # In this case, I'm expecting a new line. child.expect("\r\n") # child.before is everything that is before the expect. print(child.before) |
- You spawn the interactive program with
pexpect.spawn("/bin/bash -c ls").
- You expect what comes after the command like
\r\n (meaning new line)
or the next command you know you’ll send. child.before
is all the output before what we expect. We can print or use it in anif
clause.
ssh example. Knowing what exactly we’re expecting. Sending multiple commands.
bash
was a special example since the program allows input with its -c
flag.
What if the program doesn’t have such a flag?
Let’s say that I wanted to automate a command on another machine with ssh
.
Not just one command. Multiple commands.
Manual
ssh
into the machine.- Create a file called
slothparadise
withtouch.
ls
the current folder.
Automated
When we use pexpect
to automate the manual process, we take a look at what we expect to happen.
We pinpoint what we will see after the command.
For ssh
, it’s easy to see that after each command, we see [email protected]:~
.
We can use regex or in this case, it’s easy to use the word as it is.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import pexpect # sendline runs commands on the interactive program. # 1. Create slothparadise. # 2. ls to list the files in the current folder. child.sendline("touch slothparadise") child.sendline("ls") # We expect [email protected]:~ the first time where it happens right after the Last login: line. # But that is not when the command happens. child.expect expects words or regex expressions in order. # The second ubuntu line happens after using touch. # The third ubuntu line happens after using ls. # We can print child.before, which will contain everything before the last child.expect. print(child.before) |
regex example
You can expect uncertain output with regex.
If you don’t know what regex is, it is short for regular expression, which matches ranges of characters or words.
Let’s use regex with the ssh
example.
Instead of expecting [email protected]:~
, we give room for expecting other users like [email protected]:~
.
Who knows? The user might be on root!
If you’re not familiar with regex, then I recommend to double-check your regex with this website.
The regex detects the highlighted blue.
- We create
slothparadise2
. - We list the contents of the directory with
ls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import pexpect # sendline runs commands on the interactive program. # 1. Create slothparadise2. # 2. ls to list the files in the current folder. child.sendline("touch slothparadise2") child.sendline("ls") # We expect [email protected]:~ the first time where it happens right after the Last login: line. # The second user line happens after using touch # The third user line happens after using ls. # We can print child.before, which will contain everything before the last child.expect. print(child.before) |
Instead of the word, I used the regex expression, and it works the same as before.
Those are the basics of pexpect
! You can expand on these examples, and you’ll be on your way to scripting those tiresome interactive programs with an easy-to-use language like Python!