如何在Bash中给定超时后杀死子进程?

Gre*_*reg 161 unix linux bash

我有一个bash脚本启动一个子进程,它不时崩溃(实际上,挂起)并没有明显的原因(闭源,所以我无能为力).因此,我希望能够在给定的时间内启动此过程,如果在给定的时间后没有成功返回,则将其终止.

有没有一种简单强大的方法来实现使用bash?

PS:告诉我这个问题是否更适合serverfault或超级用户.

Ign*_*ams 244

(如下所示: BASH FAQ条目#68:"如何运行命令,并在N秒后中止(超时)?")

如果您不介意下载某些内容,请使用timeout(sudo apt-get install timeout)并使用它:(大多数系统已安装它,否则使用sudo apt-get install coreutils)

timeout 10 ping www.goooooogle.com
Run Code Online (Sandbox Code Playgroud)

如果您不想下载某些内容,请执行内部超时操作:

( cmdpid=$BASHPID; (sleep 10; kill $cmdpid) & exec ping www.goooooogle.com )
Run Code Online (Sandbox Code Playgroud)

如果您想为更长的bash代码执行超时,请使用第二个选项:

( cmdpid=$BASHPID; 
    (sleep 10; kill $cmdpid) \
   & while ! ping -w 1 www.goooooogle.com 
     do 
         echo crap; 
     done )
Run Code Online (Sandbox Code Playgroud)

  • `timeout`是GNU coreutils的一部分,因此应该已经安装在所有GNU系统中. (17认同)
  • Re Ignacio的回复以防其他人想知道我做了什么:`cmdpid = $ BASHPID`不会接受*calling*shell的pid,而是(`)`开始的(第一个)子shell.`(sleep` ...事件调用第一个子shell中的第二个子shell在后台等待10秒并杀死第一个子shell,在启动杀手子shell进程后,继续执行其工作负载...... (8认同)
  • 我并不是100%肯定,但据我所知(我知道我的manpage告诉我的内容)`timeout`现在是coreutils的一部分. (3认同)
  • 此命令不会"提前完成".它总是在超时时终止进程 - 但不会处理它没有超时的情况. (3认同)

Dan*_*Dan 26

# Spawn a child process:
(dosmth) & pid=$!
# in the background, sleep for 10 secs then kill that process
(sleep 10 && kill -9 $pid) &
Run Code Online (Sandbox Code Playgroud)

或者获取退出代码:

# Spawn a child process:
(dosmth) & pid=$!
# in the background, sleep for 10 secs then kill that process
(sleep 10 && kill -9 $pid) & waiter=$!
# wait on our worker process and return the exitcode
exitcode=$(wait $pid && echo $?)
# kill the waiter subshell, if it still runs
kill -9 $waiter 2>/dev/null
# 0 if we killed the waiter, cause that means the process finished before the waiter
finished_gracefully=$?
Run Code Online (Sandbox Code Playgroud)

  • 在尝试进程可以先处理的信号之前,不应该使用`kill -9`. (8认同)
  • 这实际上是一个非常糟糕的解决方案.如果`dosmth`在2秒内终止,另一个进程接受旧pid,你杀掉新的pid怎么办? (7认同)
  • PID回收通过达到极限并环绕来工作。另一个进程不太可能在剩余的 8 秒内重用 PID,除非系统完全失控。 (2认同)

Dig*_*oss 11

sleep 999&
t=$!
sleep 10
kill $t
Run Code Online (Sandbox Code Playgroud)