Я застрял с кодом ожидания. Это было разработано как общий код для запуска любого сценария оболочки как другого пользователя Unix на одном и том же хосте (только для того, чтобы обойти ограничение механизма автоматизации, которое может выполняться только у конкретного пользователя ОС)Tcl Expect - скрипт не заканчивается на длительный период 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 [email protected]$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
Что касается * «Ожидать никогда не прекращается, даже если дочерний процесс заканчивается» *, как вы убедитесь, что завершился детский процесс? – pynexj
@whjm проверил его в обработанном виде. Также сценарий оболочки создает свой собственный журнал, каждый раз, когда он регистрирует законченное время также в журнале. –