2015-09-23 63 views
1

我想弄清楚如何持续监视我在Expect脚本中产生的shell错误的自动SSH会话。有没有办法让后台进程连续搜索我的SSH会话输出“-ksh:”?在Expect脚本中监视产生的shell错误进程

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

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

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 [email protected]$host 
    if [catch "spawn ssh [email protected]$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

@GlennJackman我添加了一个我期望的脚本。这是许多功能/期望脚本中的一种,它们协同工作以自动处理配对配置中两台服务器上的软件安装。在此功能运行之前,“主”服务器的配置文件已经被SCP发送给合作伙伴。该配置文件将在合作伙伴上进行修改以用于安装,然后来源设置环境。在配置文件发出后,运行各个功能。 – legendmac

+0

@GlennJackman我在我的搜索中看到类似的问题,你曾使用'lassign [wait]'推荐给一个用户来检测是否发生错误。我知道我有一个足够旧的版本,期望lassign不是一种选择。我不得不使用'foreach {pid spawnid os_error_flag value} [wait] break'并检查'os_error_flag'是否返回0.但是,我已经足够新到编程期望我不确定这是否可以工作这种情况用于捕获任何shell错误并通过退出处理程序退出,或者我将如何执行它。 – legendmac

回答

0

固有的重定向我是在需要更多的工作,是无关紧要的对这个问题的评论中提到的脚本,所以我会简单地张贴的答案,期待KSH错误。

在此之前的部分### Source the configuration file ###,添加以下:

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

这本质上增加了一个期望-re块都期待以下块此代码段,包括那些在程序。它会期望KSH或shell函数出现时通常会看到的语法。