在bash脚本中使用带有SSH -t的GNU超时来防止挂起

时间:2017-05-20 04:36:21

标签: bash ssh timeout tty gnu-coreutils

我有一个ssh到某些服务器的脚本。有时意外的问题会导致ssh无限期挂起。如果运行时间过长,我想通过杀死ssh来避免这种情况。

我还使用包装函数进行输入重定向。我需要使用-t标志强制tty来使服务器上的进程开心。

function _redirect {
    if [  "$DEBUG" -eq 0 ]; then
        $*   1> /dev/null 2>&1
    else
        $*
    fi
    return $?
exit
}
SSH_CMD="ssh -t  -o BatchMode=yes -l robot"
SERVER="192.168.1.2"
ssh_script=$(cat <<EOF
sudo flock -w 60 -n /path/to/lock -c /path/to/some_golang_binary
EOF
)

_redirect timeout 1m $SSH_CMD $SERVER "($ssh_script)"

结果是打印此消息时超时:

 tcsetattr: Interrupted system call

预期结果是远程shell命令的输出,或超时和正确的退出代码。

当我输入

  timeout 1m ssh -t -o BatchMode=yes -o  -l robot 192.168.1.2 \
  "(sudo sudo flock -w 60 -n /path/to/lock -c /path/to/some_golang_binary)" \
  1> /dev/null

我得到了预期的结果。

我怀疑这两件事:

1)GNU超时和ssh之间的交互导致tcsetattr系统调用花费很长时间(或挂起),然后超时发送SIGTERM来中断它并打印该消息。没有其他输出,因为此调用是首先完成的事情之一。我想知道超时是否在没有终端的子进程中启动ssh,然后使用其主进程来计算时间并杀死其子进程。

我看了here,因为这个电话可能会失败。

2)_redirect需要$@, $*, "$@", "$*"等不同的一个。一些错误的转义/ param munging打破了超时的参数,导致这个tcsetattr错误。尝试各种组合尚未解决问题。

1 个答案:

答案 0 :(得分:2)

修正了这个--foreground flag to timeout。