10

I'm trying to instruct my Python installation to execute an Expect script "myexpect.sh":

#!/usr/bin/expect
spawn ssh usr@myip
expect "password:"
send "mypassword\n";
send "./mycommand1\r"
send "./mycommand2\r"
interact

I'm on Windows so re-writing the lines in the Expect script into Python are not an option. Any suggestions? Is there anything that can run it the way "./myexpect.sh" does from a bash shell?


I have had some success with the subprocess command:

subprocess.call("myexpect.sh",  shell=True)

I receive the error:

myexpect.sh is not a valid Win32 application.

How do I get around this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
gortron
  • 147
  • 1
  • 3
  • 10
  • ...are you asking how to run a bash script on Windows without bash? I don't even see where Python comes in here. Furthermore, you probably should give .txt extensions to your shell scripts (.sh if anything) – Mateusz Kowalczyk Jun 22 '12 at 16:43
  • @MateuszKowalczyk in a sense yes: I would like to automate running this script, from a .py file - when I run the .py file, the expect script will be called and run as part of the sequence of the .py file. – gortron Jun 22 '12 at 16:53
  • So it looks like you're not looking for a python-related solution at all (other than the fact that it's being controlled from Python). You simply want a program on Windows that will be able to read the expect script and execute it, right? – Eric Finn Jun 22 '12 at 17:20
  • @EricFinn I am looking for a python solution - the myexpect.sh runs fine if I execute it from a cygwin terminal, but that is not my final goal. What I would like to do is have my python script execute my .sh script whenever I run my .py file, so I don't have to execute it from a terminal by hand before I run my .py file. – gortron Jun 22 '12 at 17:29
  • 1
    @gortron But it looks like your question isn't really Python-specific; you're just telling the OS to run a file as a program, and a solution that will allow the OS to run said file (most likely through a Windows port of Expect) would work with any language, not just Python. Or would also reading in the script and interpreting it yourself in Python be acceptable? – Eric Finn Jun 22 '12 at 17:36
  • @EricFinn The best solution is something like pexpect functionality, where I can write the Expect lines right into my .py code. There is no pexpect library for windows (although winpexpect may prove fruitful), and subprocess is a gordian knot at my level of python expertise. I was hoping I was missing something obvious like "run myexpect.sh" but I don't think it's that simple. – gortron Jun 22 '12 at 17:45
  • Yeah, there isn't a program for running expect scripts packaged with Windows, and it doesn't really look like there's a Windows-compatible Python package to do it. – Eric Finn Jun 22 '12 at 18:37
  • it seems you want this: `subprocess.call(r"c:\path\to\cygwin\expect.exe", "myexpect.sh"])`. Your specific script could be implemented using [`fabric`](http://fabfile.org) – jfs Jan 07 '16 at 08:27

2 Answers2

24

Use the pexpect library. This is the Python version for Expect functionality.

Example:

child = pexpect.spawn('Some command that requires password')
child.expect('Enter password:')
child.sendline('password')
child.expect(pexpect.EOF, timeout=None)
cmd_show_data = child.before
cmd_output = cmd_show_data.split('\r\n')
for data in cmd_output:
    print data

Pexpect comes with lots of examples to learn from. For use of interact(), check out script.py from examples:

(For Windows, there is an alternative to pexpect.)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
pyfunc
  • 65,343
  • 15
  • 148
  • 136
  • pexpect is a brilliant solution if you're on a Linux platform, but there is no pexpect library available for Windows platforms. – gortron Jun 22 '12 at 16:50
  • @gortron: There was an SO discussion on pexpect equivalent for windows. I have added that to the answer. See if that helps. – pyfunc Jun 22 '12 at 18:54
  • For posterity: winpexpect is a clean solution. – gortron Jun 22 '12 at 20:03
  • @gortron: Thanks! It has been long since I have been on windows platform. – pyfunc Jun 22 '12 at 20:21
  • @gortron: there is no `ssh` command on Windows. I don't see how using `winpexpect` would help here. – jfs Jan 07 '16 at 08:29
  • @pyfunc i'm trying to setup a SSH tunnel with dual step authentication but unable to get the second prompt. I just wanted to `sendline` for the first prompt but want manual input for second prompt or may be third one as well, which is a value from MFA. Thanks in advance. – Hardeep Singh Apr 15 '20 at 11:44
  • License may be unwelcome in many companies – uchuugaka Dec 16 '22 at 23:01
0

Since it is an .expect script, I think you should change the extend name of your script.

Instead of using

subprocess.call("myexpect.sh", shell=True)

you should use

subprocess.call("myexpect.expect", shell=True)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MaxGu
  • 71
  • 4