Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ssh 在Expect脚本中监视生成的进程的shell错误_Ssh_Error Handling_Ksh_Expect - Fatal编程技术网

Ssh 在Expect脚本中监视生成的进程的shell错误

Ssh 在Expect脚本中监视生成的进程的shell错误,ssh,error-handling,ksh,expect,Ssh,Error Handling,Ksh,Expect,我正试图弄清楚如何持续监视我在Expect脚本中生成的自动SSH会话以发现shell错误。有没有一种方法可以让后台进程持续搜索SSH会话的输出,以查找“-ksh:” 在KSH中,我只会捕获ERR信号,但ERR在Expect中不是有效的信号类型。关键是我想监控shell错误,这样我就可以通过退出处理程序而不是期望脚本继续执行 下面是我的一个shell函数/expect脚本的片段。专门的Expect程序被排除在外,因为它们与问题无关。这个特定的Expect脚本生成和SSH会话到伙伴服务器,并生成/运

我正试图弄清楚如何持续监视我在Expect脚本中生成的自动SSH会话以发现shell错误。有没有一种方法可以让后台进程持续搜索SSH会话的输出,以查找“-ksh:”

在KSH中,我只会捕获ERR信号,但ERR在Expect中不是有效的信号类型。关键是我想监控shell错误,这样我就可以通过退出处理程序而不是期望脚本继续执行

下面是我的一个shell函数/expect脚本的片段。专门的Expect程序被排除在外,因为它们与问题无关。这个特定的Expect脚本生成和SSH会话到伙伴服务器,并生成/运行几个用户定义的shell函数。当初始化并执行init_log函数时,会创建日志文件,并将STDOUT/STDERR重定向到这些日志,因此需要使用tee/dev/tty命令,以便从伙伴服务器上运行的函数中查看STDOUT。我不确定是否应该暂时将STDERR重定向到屏幕上,并在每个expect块上使用“-ksh:”,或者是否有一种更简单、更可靠的方法来监视SSH会话期间是否在任何时候发生shell错误

function exp_run_funcs {
# Check for DEBUG mode
[[ -n $DEBUG ]] && typeset PS4="$0: " && set -x  

# Log status message
log_stdout $0 "Running functions on the $rsvr server."

# Run functions on remote host
expect -c "set logdir $sai_logdir; set dlogfl $detailflnm;\
set ulogfl $usrflnm; set prgmfunc \"$program $0\"; set remsvr $rsvr;\
set user $usr; set host ${ip_ad[$rind]}; set pwd $pswd;\
set cfgfl $sai_cfgflnm; set sai_chksum \"$chksum\"" -c '

    ########## INITIALIZATION ##########
    ### Expect environment initialization ###
    set timeout 15
    log_user 0
    set prompt "(%|#|>|\\\$) $"
    set status 1 ; # Initialize status to failure

    ########## ESTABLISH SSH CONNECTION TO REMOTE SERVER ##########
    spawn -noecho ssh $user@$host
    if [catch "spawn ssh $user@$host" reason] {
        puts "Failed to establish SSH connection\
        to $remsvr server ($host): $reason.\n"
        set status 3
        exit $status
    }

    ### Set responses for expected login prompts ###
    expect {
        -re "(.*)assword:" { 
            send "$pwd\r"               
        }
        "you sure you want to continue connecting" {
            send -s "yes\r"
            exp_continue
        }
        timeout {
            set status 4
            exit $status
        }
        eof {
            set status 5
            exit $status
        }
    }

    expect -re $prompt {
        set timeout -1

        ### Source the configuration file ###
        puts "Sourcing the configuration file on the\
        $remsvr server.\n"

        send ". $cfgfl\r"
        if [catch "send \". \$cfgfl\r\"" reason] {
            puts "Failed to source the configuration file:\
            $reason.\n"
            set status 9
            exit $status
        }
        expect -re "(.*)config.ini\r\n(.*)$prompt"

        ### Run individual functions ###
        set timeout 15
        set tdir "$logdir/tmp"
        set fcnlst "init_log init_env install_func\
            srv_setup" 

        foreach fcn $fcnlst {
            puts "Sourcing and running function $fcn.\n"

            if {[run_function "$fcn"] != 0} {
                exit $status
            }
            if {$fcn != "init_log"} {puts "\n"}
            merge_logs
        }

        expect -re $ { set status 0 }
    }
' | tee /dev/tty
}

注释中提到的脚本中固有的重定向需要更多与此问题无关的工作,因此我将简单地发布预期KSH错误的答案

########
部分之前,我添加了以下内容:

### Expect any KSH or function errors ###
expect_before -re "-ksh(.*): | (.*):(.*): " {set status 12; exit $status}

这实质上是向该代码段后面的所有expect块(包括过程中的块)添加一个expect-re块。当出现KSH或shell函数错误时,它将使用通常看到的语法。

注释中提到的脚本中固有的重定向需要更多与此问题无关的工作,因此我将简单地发布预期KSH错误的答案

########
部分之前,我添加了以下内容:

### Expect any KSH or function errors ###
expect_before -re "-ksh(.*): | (.*):(.*): " {set status 12; exit $status}

这实质上是向该代码段后面的所有expect块(包括过程中的块)添加一个expect-re块。当出现KSH或shell函数错误时,它将使用通常看到的语法。

显示您的代码会很有帮助。@GlennJackman我已经添加了一个expect脚本。这是许多函数/expect脚本之一,它们协同工作以自动处理成对配置中两台服务器上的软件安装。在运行此功能之前,“主”服务器的配置文件已发送给合作伙伴。将在合作伙伴上修改配置文件,以便在安装中使用,然后从源代码中设置环境。配置文件来源后,将运行各个函数。@GlennJackman我在搜索中看到了类似的问题,您使用
lassign[wait]
来检测是否发生了错误。我知道我有一个足够古老的版本,期望lassign不是一个选项。我必须使用
foreach{pid spawnid os_error_flag value}[wait]break
并检查
os_error_flag
是否返回0。但是,我对编程还很陌生,我不确定在这种情况下,捕获任何shell错误并通过exit处理程序退出是否有效,或者我将如何实现它。在开始运行函数之前,请定义一个
Expect\u after
模式来查找shell错误字符串。类似于
在“err”{call my cleanup code}之后使用expect\u
。expect\u after基本上是将模式和操作(或多个)附加到后面的每个
expect
命令。@GlennJackman您是在调用run\u函数之前定义expect\u after,还是在expect-re$提示符之前成功连接到合作伙伴服务器之后定义expect\u?然后,它会将模式和操作附加到SSH会话期间发生的所有expect命令,对吗?显示您的代码会很有帮助。@GlennJackman我已经添加了一个expect脚本。这是许多函数/expect脚本之一,它们协同工作以自动处理成对配置中两台服务器上的软件安装。在运行此功能之前,“主”服务器的配置文件已发送给合作伙伴。将在合作伙伴上修改配置文件,以便在安装中使用,然后从源代码中设置环境。配置文件来源后,将运行各个函数。@GlennJackman我在搜索中看到了类似的问题,您使用
lassign[wait]
来检测是否发生了错误。我知道我有一个足够古老的版本,期望lassign不是一个选项。我必须使用
foreach{pid spawnid os_error_flag value}[wait]break
并检查
os_error_flag
是否返回0。但是,我对编程还很陌生,我不确定在这种情况下,捕获任何shell错误并通过exit处理程序退出是否有效,或者我将如何实现它。在开始运行函数之前,请定义一个
Expect\u after
模式来查找shell错误字符串。类似于
在“err”{call my cleanup code}之后使用expect\u
。expect\u after基本上是将模式和操作(或多个)附加到后面的每个
expect
命令。@GlennJackman您是在调用run\u函数之前定义expect\u after,还是在expect-re$提示符之前成功连接到合作伙伴服务器之后定义expect\u?然后,它会将模式和操作附加到SSH会话期间发生的所有expect命令,对吗?