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

时间:2015-09-23 18:00:47

标签: ssh error-handling ksh expect

我试图弄清楚如何持续监控我在Expect脚本中为shell错误生成的自动SSH会话。有没有办法让后台进程不断搜索我的SSH会话输出" -ksh:"?

在KSH中,我只是捕获E​​RR信号,但ERR在Expect中不是有效的信号类型。关键是我要监视shell错误,以便我可以通过我的退出处理程序而不是Expect脚本继续执行。

下面是我的一个shell函数/ expect脚本的片段。排除了专门的Expect程序,因为它们与该问题无关。此特定Expect脚本生成和SSH会话到伙伴服务器,并且源/运行多个用户定义的shell函数。当源和执行init_log函数时,会创建日志文件并将STDOUT / STDERR重定向到那些日志 - 因此需要tee / dev / tty命令以便我可以从我在伙伴服务器上运行的函数中看到STDOUT 。我不确定是否应暂时将STDERR重定向到屏幕并期望" -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
}

1 个答案:

答案 0 :(得分:0)

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

### Source the configuration file ###部分之前,我添加了以下内容:

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

这实际上会在此代码段后面的所有expect块中添加一个expect -re块,包括过程中的那些块。它会出现KSH或shell函数出现时通常会看到的语法。