shell expect SSH用法一例

本文重点解决两个问题:shell

  1. 获取SSH远程执行命令的返回状态
  2. expect执行SSH时进程中不显示密码明文

先上Shell 代码:bash

export IP CMD SSH_PWD
expect << 'END'
# 关闭输出
log_user 0
set timeout 30
# 从系统变量获取数据
set ip "$env(IP)"
set cmd "$env(CMD)"
set pwd "$env(SSH_PWD)"
spawn ssh root@$ip "$cmd"
expect {
    "(yes/no)?"                           {send "yes\r";exp_continue}
    # 忽略大小写
    -nocase "password:"                   {send "$pwd\r";exp_continue}
    # 登陆成功,打开输出
    -nocase "authentication successful"   {log_user 1;exp_continue}
    # 登陆失败
    -nocase "authentication fail"         {exit 222}
    -nocase "permission denied"           {exit 222}
    eof
}
puts $expect_out(buffer)
lassign [wait] pid spawnid os_error_flag value
# 系统错误
if {$os_error_flag == -1} {
    puts "os errno: $value"
} else {
    # 返回 CMD 执行结果
    exit $value
}
END
exitCode=$?
if [ $exitCode -eq 222 ]; then
    echo 'log error'
elif [ $exitCode -ne 0 ]; then
    echo 'cmd error'
fi

获取执行结果的关键在于【wait】方法的使用:ssh

wait [args]spa

delays until a spawned process (or the current process if none is named) terminates.线程

wait normally returns a list of four integers. The first integer is the pid of the process that was waited upon. The second integer is the corresponding spawn id. The third integer is -1 if an operating system error occurred, or 0 otherwise. If the third integer was 0, the fourth integer is the status returned by the spawned process. If the third integer was -1, the fourth integer is the value of errno set by the operating system. The global variable errorCode is also set.code

【wait】:延迟直到一个spawn进程结束。返回4个数值:orm

  1. expect 进程 pid
  2. spawn 线程 id
  3. OS状态值(-1:系统错误,0:正常)
  4. spawn命令返回值(OS值为 -1时返回OS错误代码,为 0时返回CMD退出值)

参考:expect manHow to get the exit code of spawned process in expect shell script?进程

开头的两个问题都获得了解决:ip

  • 使用 wait 获取SSH 远程执行命令的返回状态,登陆失败也能够经过指定状态码(222)标识;
  • 使用 env 读取外部变量到expect 变量中,从而 PS 不会显示 密码明文。
相关文章
相关标签/搜索