Search code examples
crashwaitexpectrsync

Using wait on spawned rsync process stops rsync in expect


I have a simple expect script that starts a rsync process and sends the password. After that i am using wait in order to catch the result code of the rsync process:

#!/usr/bin/expect

# check arguments
if { $argc != 3 } {
    puts "Usage $argv0 src dest password"
    exit 1
}

# set arguments
set src [lindex $argv 0]
set dest [lindex $argv 1]
set password [lindex $argv 2]

# call rsync
spawn rsync --delete --exclude=.svn  -rvae ssh $src $dest

# confirm connect question
set timeout 2
expect {
    *connecting* {send "yes\r"}
}

# send password
set timeout 5
expect {
    *assword: {send "$password\r"}
}

# invalid password
set timeout 2
expect {
    *denied* {exit 2}
}

# get process result
lassign [wait] pid spawnid os_error_flag value

# exit with error code
exit $value

The problem is that 2 seconds after I see the password prompt (probably after the "invalid password" block times out) rsync crashes. It just stops transmitting and even Ctrl-C can't kill expect anymore. Debugging prove that the wait command causes this behaviour. Before I was using

set timeout -1
expect eof

and everything worked fine. But that way I couldn't retrieve the result code of rsync.

Is there a problem in my expect script or is this a bug in the wait command or rsync?


Solution

  • You can wait after expect eof. For example:

    % cat foo.exp
    spawn sh -c "exit 17"
    expect eof
    set waitResult [wait]
    send_user $waitResult\n
    % expect foo.exp
    spawn sh -c exit 17
    29293 exp7 0 17
    %