Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have an expect script embedded in a bash script:

#! /bin/bash

# this function runs a command like 'ssh' and provides the password
function with_password {
expect << END
spawn $2
expect *assword:*
send -- $1
interact
wait
END
}

# run "long_running_command" on the remote server
with_password my_password "ssh my_user@some-server long_running_command"

# rsync some data to the remote server
with_password my_password "rsync /some/dir my_user@some-server:/remote/dir"

# run some other random command
with_password my_password "ssh my_user@some-server some_other_command"

The problem is that sometimes the script will hang while waiting for a spawned command. If I leave the wait command out of the expect script, the command will continue to run on the remote server, but the bash script will continue, and I have no way of knowing when it finishes.

Why does my expect script seem to be randomly hanging?

share|improve this question
add comment

3 Answers

up vote 2 down vote accepted

The interact command in the expect here-doc was the problem. I needed to wait for EOF instead:

#! /bin/bash

# this function runs a command like 'ssh' and provides the password
function with_password {
expect << END
set timeout 900
spawn $2
expect *assword:*
send -- $1
expect EOF
END
}

# run "long_running_command" on the remote server
with_password my_password "ssh my_user@some-server long_running_command"

# rsync some data to the remote server
with_password my_password "rsync /some/dir my_user@some-server:/remote/dir"

# run some other random command
with_password my_password "ssh my_user@some-server some_other_command"

The interact command seem to work sometimes when the ssh/rsync command closed the input at the correct time (maybe?), but it wasn't reliable.

share|improve this answer
add comment

You are missing the final here doc delimiter.

expect << END
spawn $2
expect *assword:*
send -- $1
interact
wait
END
share|improve this answer
    
Thnx for pointing that out, though that is there in the code; I made a typo transcribing it. –  aaron Sep 2 '10 at 3:13
    
@aaron: I see that you added it back in your question, but it's after the closing curly brace. I assume it's also a transcription error. –  Dennis Williamson Sep 2 '10 at 8:35
    
Thanks, I fixed it again –  aaron Sep 2 '10 at 11:52
add comment

What about using passwordless logins with ssh keys?

You can create your keys with ssh-keygen then put your public key on the remote end: ~/.ssh/authorized_keys.

You can even create keys with passphrase (if you want to add some kind of security) which you can load in your shell with ssh-agent bash enter you pass once, and it will keep your unlocked key in the memory for later password promptless logins.

share|improve this answer
    
I know about public key authentication and there are reasons why that won't work in my case. Any ideas why the expect script is behaving unexpectedly? –  aaron Sep 2 '10 at 3:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.