【发布时间】:2016-12-17 03:25:35
【问题描述】:
我被期望代码困住了。这是作为通用代码开发的,可以在同一主机上以另一个 Unix 用户身份运行任何 shell 脚本(只是为了规避只能在特定操作系统用户中执行的自动化引擎的限制)
如果生成(作为 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
【问题讨论】:
-
关于“即使子进程完成,expect也不会终止”,你是如何检查子进程是否完成的?
-
@whjm 已将其签入已处理。此外,shell 脚本还会创建自己的日志,每次在日志中记录完成时间。