Linux – Use expect in shell scripts

Use expect in shell scripts… here is a solution to the problem.

Use expect in shell scripts

I need to pass two parameters to expect, the first is the command to execute, and the second is the password.

This is my expect.sh

#!/usr/bin/expect
spawn [lrange $argv 0 0]
expect "password:"
send [lindex $argv 1]
interact

Main script:

./expect.sh "ssh root@$SERVER1"  $SERVER1_PASS

Error:

couldn't execute "{ssh [email protected]}": no such file or directory
    while executing
"spawn [lrange $argv 0 0]"
    (file "./expect.sh" line 2)

Why?

Solution

As far as I know, the first argument to spawn needs to be a string, not a list of strings.

And trying to pass the multi-word command line as a single string causes problems. I think you have to split by space before calling spawn, this will break if one argument contains spaces. Perhaps it is better to specify the password as the first parameter and the command as the rest.

So try something like this:

#!/usr/bin/expect
spawn [lindex $argv 1] [lrange $argv 2 end]
expect "password:"
send [lindex $argv 0]
interact

But even that won’t work.

According to Re: expect – spawn fails with argument list comp.lang.tcl ( Google Groups version), we must call eval to split the list.

So the answer should be:

#!/usr/bin/expect
eval spawn [lrange $argv 1 end]
expect "password:"
send [lindex $argv 0]
interact

Finally, you need

to send Enter after the password, so you need to:

#!/usr/bin/expect
eval spawn [lrange $argv 1 end]
expect "password:"
send [lindex $argv 0]
send '\r'
interact

Then reverse the order and call without referencing the command:

./expect.sh "$SERVER1_PASS" ssh root@$SERVER1

But others have already done so. We don’t need to reinvent the wheel.

See also< for examplea href="http://bash.cyberciti.biz/security/expect-ssh-login-script/" rel="noreferrer noopener nofollow">expect ssh login script

Related Problems and Solutions