【问题标题】:I'm trying to find a alternative for timeout in bash 3我正在尝试在 bash 3 中找到超时的替代方法
【发布时间】:2021-10-26 03:48:22
【问题描述】:

我尝试了一种使用超时来识别并退出服务器进入 RUNNING 状态或在超时值处退出监视 RUNNING 状态的方法,不幸的是其中一个服务器具有 bash 版本 3 并且不支持超时。

timeout 300s grep -q 'Server state changed to RUNNING' <(tail -f AdminServer.out)
if [ $? != 0];then
  printf "\n===> unable to bring up the server.please check\n"
else
  printf "\n===> server came to RUNNING state\n"
fi

我尝试了以下方法,但在出现日志时无法退出

( cmdpid=$BASHPID; (sleep 60; kill $cmdpid) & exec `grep -q 'Server state changed to RUNNING' <(tail -f AdminServer.out)`)

但它首先给出grep -q 'Server state changed to RUNNING' &lt;(tail -f AdminServer.out) 的命令行替换错误,然后给出如下所示的kill 用法错误(似乎kill 不起作用), kill: 用法:kill [-s sigspec |等等……

  • 很遗憾,我无法升级服务器的 bash 版本,对此高度赞赏的任何指导。谢谢!!

*服务器:suse 发行版 2.6.32.12-0.7-default

【问题讨论】:

  • Bash 不支持超时,因为它是一个外部命令。它是 ubuntu 和 centos 中 coreutils 的一部分。我没有要检查的 suse 系统,但是如果缺少它,您可能可以获取源代码并进行编译。
  • @user1672382 :这与 bash 无关,因为 timeout 无论如何都不是内部 bash 命令。但是,如果 Suse 2.6 不包含 timeout 命令,我会感到惊讶。也许他们在非标准目录中拥有它?我会在 [Suse|(forums.opensuse.org) 上问这个问题。除了 bash,还有哪些其他语言可用?许多编程语言(Perl、Tcl、...)都具有执行超时控制的功能,因此您可以在其中一种中编写包装器。
  • exec `grep -q 'Server state changed to RUNNING' &lt;(tail -f AdminServer.out)` 定义不明确; grep -q 永远不会输出任何东西,所以exec 没有任何东西可以执行。
  • unix.stackexchange.com/questions/156131/… 有一些在给定时间后发送信号的正确方法示例。

标签: bash shell suse


【解决方案1】:

考虑尝试这样的事情:

data=$(
    tail -f AdminServer.out & pid=$!
    
    till=$[SECONDS+300]
    while ((SECONDS<till)); do :; done
    kill -9 $pid
)

grep -q 'Server state changed to RUNNING' <<< "$data" \
     && printf "\n===> server came to RUNNING state\n" \
     || printf "\n===> unable to bring up the server.please check\n"

【讨论】:

  • 你不应该经常使用kill -9,当然也不推荐给其他人。另见useless use of kill -9.
  • 即使对于 Bash v3,也可能更喜欢 POSIX $((arithmetic expression)) 语法而不是过时的 Bash-only 并且坦率地说没有吸引力的 $[expression] 语法,特别是因为您已经在脚本的其他地方使用它。
  • 即使在成功的情况下,这也必然要等待五分钟,即使它立即成功。
  • 我给出了这个想法,它有它的缺点,所以要么使用它,要么放弃它)
【解决方案2】:

当我年轻的时候...在 OSF1、DEC Alpha、SPARC... 没有timeout 命令,没有&lt;(...)&lt;&lt;&lt; 运算符... 我正在积极等待...

文件:timeout.sh

#! /bin/bash

PID="$1"
SEC="$2"
FILE="$3"

DATE_REF=$(date +%s)
DATE_MAX=$(( DATE_REF + ${SEC} ))

while ps -p "${PID}" >/dev/null 2>&1 && [[ $(date +%s) -lt ${DATE_MAX} ]] && ! grep OK "${FILE}" >/dev/null 2>&1; do
    sleep 1
done

if grep OK "${FILE}" >/dev/null 2>&1; then
    RET=0
else
    RET=1
fi

if ps -p "${PID}" >/dev/null 2>&1; then
    kill -9 "${PID}"
fi

rm -f "${FILE}"

exit $RET

这样使用:

nb_seconds_to_wait=5
tail -f my_log_file | grep -m 1 my_token_to_search && echo "OK" > my_flag_file &
timeout.sh $! nb_seconds_to_wait my_flag_file
if [[ $? -eq 0 ]]; then
    echo "Found"
else
    echo "Not found"
fi

【讨论】:

    【解决方案3】:

    我再次尝试并想出了以下内容,我在这里做了什么有害的事情吗?

    ( cmdpid=$BASHPID; ( sleep 10; if ps -p $cmdpid > /dev/null; then kill $cmdpid > /dev/null;fi ) & while `tail -f -n0 AdminServer.out | grep -q RUNNING`; do exit 0;done )
    echo "proceeding with the rest of commands the previous command status is $?"
    

    【讨论】:

    • 命令替换仍然不打印任何东西;为什么你认为这些命令需要反引号?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 2019-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多