Tcl Expect - 脚本不会因长时间运行的spawn而终止

时间:2016-12-16 16:27:15

标签: ssh tcl expect

我遇到了Expect代码。这是作为通用代码开发的,可以将任何shell脚本作为同一主机中的另一个Unix用户运行(仅仅是为了规避只能在特定OS用户中执行的自动化引擎的限制)

如果spawn(作为SSH调用)在短时间内终止,即在超时内终止,脚本将正确终止。

但是,预期的过程可以根据所涉及的数据在不同时间完成。

如果子进程在超时时间内运行的时间较长,则即使子进程完成,期望也永远不会终止。

#!/usr/bin/expect
#  Program Name         : generic_run_shell_as_user.expect
#
#  Language/Shell       : Tcl EXPECT : (http://www.tcl.tk/man/expect5.31/expect.1.html)
#
#  Description          : The purpose of this script is to use expect command to execute a shell script as another user 
#
#  Parameters           : <Pre Exec Env File With Path | - > <Shell Script With Path> [<...Shell Script Argument List...>] <Execution User Name> <Password>
#
#  Returns              :  Return Values   : Return code of the job run
#  Called
#  scripts/programs     : None
#
#  Called from
#  scripts/programs     : Job scheduler
#
#  Execute Mode
#  (batch/interactive)  : Batch
#
#  Author               : 
#
#  Date written         : 24-Sep-2016
#
#  Modification history :
#  Description of change                Date            Modified by
#  ---------------------                -----           -----------
set usage "$argv0 Environment_File_With_Path Shell_Script_With_Path Shell_Script_Argument_List_Optional Execution_User_Name Password"
set timeout 60
set success_code 0
set failure_code 255
#Check Number of Arguments being passed
if { [llength $argv] < 4} {
    puts "Usage : $usage";
    exit $failure_code
}
#Get the hostname , as script is running as 
set host_name [exec hostname]
set arg_last_indx [expr [llength $argv]-1]
set env_file [lindex $argv 0]
if {$env_file == "-"} {
    set env_file_exec ""
} else {
    set env_file_exec ". $env_file &&"
}
#puts $env_file_exec
set script [lindex $argv 1]
set username [lindex $argv [expr $arg_last_indx-1]]
set passwd [lindex $argv $arg_last_indx]
# remove the last two (user name / password) and then the first 2 elements (env file and script) from the arg list
set argv_nw [lreplace [lreplace $argv [expr $arg_last_indx-1] $arg_last_indx] 0 1]
#invoke ssh and connect with new user ,give the env file execution and the script execution with trimmed list as arguments
spawn ssh $username@$host_name $env_file_exec sh $script $argv_nw \r\n

# in case if remote server key is not already imported. reply to the prompt for adding as yes
expect "yes/no" { 
                 send "yes\r\n"
                 }
#pass the input password as reply for the password prompt (handle case of Password and password)                 
expect "*?assword" {  
                   send "$passwd\r"                
                 }
#if the password is wrong , exit citing wrong password               
expect "Permission denied, please try again." {
                       puts "Password is wrong";
                       exit $failure_code
                 }               
expect eof               
# wait until the ssh session terminates and capture its exit code                
catch wait result
set exit_code [lindex $result 3]
#print the exit code of script and exit with same code , for invoker to fail
puts "Exit Code of $script : $exit_code"
exit $exit_code

1 个答案:

答案 0 :(得分:0)

如果命令需要任意时间,请在预期eof:

之前重置超时
set timeout -1
expect eof