bash 为 shell 脚本设置超时,使其在时间结束时退出(0)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38117000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:50:49  来源:igfitidea点击:

Set timeout for shell script, to make it exit(0) when time is over

linuxbashshelljenkins

提问by Reed_Xia

When I set up a Jenkins job and found a problem about timeout for shell script.

当我设置 Jenkins 作业并发现有关 shell 脚本超时的问题时。

It works like this:

它是这样工作的:

Start Jenkins → control.shis launched → test1.shis launched in control.sh

启动 Jenkins →control.sh启动 →test1.sh启动于control.sh

Part code of control.shis like:

部分代码control.sh如下:

#!/bin/sh
source func.sh     

export TIMEOUT=30
# set timeout as 30s for test1.sh

( ( sleep $TIMEOUT && function_Timeout ) & ./test1.sh ) 
# this line of code is in a = loop actually
# it will launch test2.sh, test3.sh... one by one
# later, I want to set 30s time out for each of them.

function_Timeout() {
  if [ ! -f test1_result_file]: then
    killall test1.sh
    # the test1_result_file will not 
    # be created if test1.sh is not finished executing.
  fi
}

part of func.sh is as below

func.sh 的一部分如下

#!/bin/sh
function trap_fun() {
  TRAP_CODE=$?
  { if [ $TRAP_CODE -ne 0 ]; then
      echo "test aborted"
    else
      echo "test completed"
  } 2>/dev/null

trap "trap_fun" EXIT

After control.shis launched by Jenkins job, the whole control.shwill be terminated when time is over, and the line of killall test1.shis reached, and the Jenkins job stop and fail.

control.shJenkins 作业启动后,control.sh时间一到,整体将终止,killall test1.sh到达行,Jenkins 作业停止并失败。

I guess it's because test1.shis killed and exit code is not 0, so it cause this problem.

我猜是因为test1.sh被杀死而退出代码不是0,所以它导致了这个问题。

So my question is, is there someway to terminate or end the sub-script (launched by the main one, like control.shin my case) exit with code 0?

所以我的问题是,有没有办法终止或结束子脚本(由主脚本启动,就像control.sh我的情况一样)退出代码0

Updated on July 1:

7 月 1 日更新:

Thanks for the answers so far, I tried @Leon's suggestion, but I found the code 124 sent by timeout's kill action, is still caught by the trap code - trap "trap_fun" EXIT, which is in func.sh.

感谢到目前为止的答案,我尝试了@Leon 的建议,但我发现超时的终止操作发送的代码 124 仍然被陷阱代码捕获 - 陷阱“trap_fun”EXIT,它在 func.sh 中。

I added more details. I did a lot google job but still not found a proper way to resolve this problem:(

我添加了更多细节。我做了很多谷歌工作,但仍然没有找到解决这个问题的正确方法:(

Thanks for your kind help!

感谢您的帮助!

采纳答案by Reed_Xia

I resolved this problem finally, I added the code below in each testX.sh.

我最终解决了这个问题,我在每个 testX.sh 中添加了下面的代码。

trap 'exit 0' SIGTERM SIGHUP

It is to make test1.sh exit normally after it receives killall signal.

就是让test1.sh在收到killall信号后正常退出。

Thanks to all the help!

感谢所有的帮助!

回答by Leon

Use the timeoututility from coreutils:

使用以下timeout实用程序coreutils

#!/bin/sh

timeout 30 ./test1.sh
status=$?
if [ $status -eq 124 ] #timed out
then
    exit 0
fi
exit $status

Note that this is slightly different from your version of timeout handling, where all running instances of test1.share being terminated if any one of them times out.

请注意,这与您的超时处理版本略有不同,test1.sh如果其中任何一个超时,则所有正在运行的实例都将被终止。