本文重点解决两个问题:
- 获取SSH远程执行命令的返回状态
- expect执行SSH时进程中不显示密码明文
先上Shell 代码:
export IP CMD SSH_PWDexpect << 'END'# 关闭输出log_user 0set 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}ENDexitCode=$?if [ $exitCode -eq 222 ]; then echo 'log error'elif [ $exitCode -ne 0 ]; then echo 'cmd error'fi
获取执行结果的关键在于【wait】方法的使用:
wait [args]
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.
【wait】:延迟直到一个spawn进程结束。返回4个数值:
- expect 进程 pid
- spawn 线程 id
- OS状态值(-1:系统错误,0:正常)
- spawn命令返回值(OS值为 -1时返回OS错误代码,为 0时返回CMD退出值)
参考:、
开头的两个问题都得到了解决:
- 使用 wait 获取SSH 远程执行命令的返回状态,登录失败也可以通过指定状态码(222)标识;
- 使用 env 读取外部变量到expect 变量中,从而 PS 不会显示 密码明文。