On Monday, June 8, 2015 at 12:39:24 PM UTC+2, Guido Avvisati wrote:
> I am trying to set up an expect script to automate an scp copy on multiple servers. For some unknown reasons, I need to spawn a shell to get it to work, but this is OK by me. The problem is that I cannot seem to close/exit/kill this shell after I successfully do the scp. Here is the script
Maybe my version helps:
vvvvvvvvvvvvvvvvvvvvvvvvvv
# argument handling above
# do scp
global spawn_id
set ret true
if {0 == [::spawn -noecho scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o NumberOfPasswordPrompts=1 $src $dst]} {
::logger::tree::lib::error "{[::info level 0]} cannot spawn scp."
set ret false
} else {
set sid $spawn_id
expect {
-i $sid
-ex "assword: " {
exp_send -i $sid "$passwd\r"; exp_continue
}
-ex "ermission denied" {
::logger::tree::lib::error "{[::info level 0]} wrong password."
set ret false
}
-re {[\r\n]} {
exp_continue
}
timeout {
::logger::tree::lib::error "{[::info level 0]} timed out."
set ret false
}
eof {
::logger::tree::lib::info "{[::info level 0]} completed."
}
}
# close the spawned process
::lib::wait $sid sid
if {$sid} {
::logger::tree::lib::error "{[::info level 0]} scp returned a non-zero exit code {$sid}."
set ret false
}
}
return $ret
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
where ::lib::wait is
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# waits for the current child process to terminate.
# This releases the spawn id and its resources.
# @param sid the spawn id like the parameter <code>-i</code>
# of <code>send</code>. <code>$::spawn_id</code> by default
# @param ec the name of the variable to receive the exit code on success
# @return <code>true</code> on success, <code>false</code> else
proc wait {{sid {}} {ec {}}} {
if {{} eq $sid} {
return ::lib::wait $::spawn_id
}
if {{} ne $ec} {
upvar 1 $ec myec
}
catch {close -i $sid}
set ret false
if {[catch {::wait -i $sid} ret]} {
::logger::tree::lib::warn "Error while waiting for $sid."
catch {::wait -nowait -i $sid}
return false
} elseif {[lindex $ret 2]} {
::logger::tree::lib::warn "System error [lindex $ret 3] while waiting for $sid."
return false
} else {
set myec [lindex $ret 3]
::logger::tree::lib::debug "{$sid} has terminated with status {$myec}."
return true
}
# UNREACHABLE
}
# Cannot export this proc. It conflicts with a built-in proc.
# namespace export wait
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^