我正在编写一些自动化程序,遇到了一个问题,主机的密钥已更改,并且出现了问题。我想针对此特定情况添加飞行前检查,但似乎无法返回ssh
除其 255 全部返回代码之外的任何内容。
例如:
$ ssh -o StrictHostKeyChecking=yes foobar@squiffy-host ls; echo $?
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
...snip...
255
我怎样才能检测到这个,具体的案件?
答案1
在你的 shell 代码片段上进行一点构建,你可以尝试这个:
$ ssh -o StrictHostKeyChecking=yes foobar@squiffy-host ls 2>&1 |grep "WARNING: POSSIBLE DNS SPOOFING DETECTED" >/dev/null; echo $?
0
如果 grep 调用发现错误消息,则应该输出 0,如果没有,则输出 1。
答案2
此时,我并不十分乐观地认为有一个完美的答案,因此我按照你的建议来解析错误文本。
## Return codes:
# 0: No problem
# 1: Host key problem
# 2: Unhandled error
function testhostkey() {
user=$1
hostname=$2
res=$( ( ssh -o StrictHostKeyChecking=yes ${user}@${hostname} exit 1>/dev/null ) 2>&1 )
code=$?
if [ $code -eq 0 ]; then
return 0
elif [ $code -eq 255 ]; then
while read line; do
case "$line" in
'WARNING: POSSIBLE DNS SPOOFING DETECTED!')
continue
;;
'WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!')
continue
;;
*)
echo "Unhandled SSH error message: $line" >&2
echo "$res" >&2
return 2
;;
esac
done < <(echo "$res" | grep '^@\s\+' | sed 's/@\s\+\(.*\)\s\+@/\1/' | sed -e 's/^\s\+//' -e 's/\s\+$//')
return 1
else
printf "Unhandled return code from SSH: %d\n%s\n" $code "$res" >&2
return 2
fi
}
基本上,如果返回代码为 255和所有错误消息都在指定集合内然后返回代码为1。
所有其他错误消息/代码均返回 2,无错误则返回 0。