3

AIX中的timeout脚本

 3 years ago
source link: https://www.lujun9972.win/blog/2021/07/27/aix%E4%B8%AD%E7%9A%84timeout%E8%84%9A%E6%9C%AC/index.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

AIX中的timeout脚本

AIX 下没有现成的 timeout 命令来限时运行命令,于是就想着自己实现一个类似的脚本。本来以为挺简单的一件事情,结果埋者一堆坑。

最后的结果如下:

#! /usr/bin/ksh
waitfor=$1
shift
command=$*
$command &
commandpid=$!
(sleep $waitfor;kill $commandpid) & # 坑1
watchdogpid=$!
wait $commandpid
kill $watchdogpid               # 坑2

这里有两个需要关注的地方:

  1. (sleep $waitof;kill $commandpid) & 在超时杀掉工作命令后就退出了,工作命令被杀掉之后 wait $commandpid 执行完成,主进程继续执行 kill $watchdogpid. 然而由于监控进程早已退出,在忙碌的系统中,可能出现 $watchdogpid 被其他进程重复使用,导致误杀其他进程的风险。 要解决这一风险,可以让监控进程在杀掉工作进程后再等待一段时间,以便让主进程杀掉监控进程。
  2. kill $watchdogpidksh 中并不会把子进程一起杀掉,也就是说 sleep $waitfor 这个进程依然在运行,只不过父进程从 $watchdogpid 变成了 1. 不仅如此 AIX 上的 kill 居然不支持 PID 为负数的情况,这使得妄想通过 kill -$watchdogpid 杀掉整个进程组变得不可能。

最后经过尝试,发现在ksh交互模式下,用 kill %jobID 的方式是能够将整个 JOB 杀干净的,因此最后的结果如下:

#! /usr/bin/ksh -i
waitfor=$1
shift
command=$*
$command &
commandpid=$!
(sleep $waitfor;kill $commandpid;sleep 1) &
wait $commandpid
kill %2 >/dev/null 2>&1

不过这种实现有个比较大的缺点就是由于整个实现实在交互式ksh环境中执行的,因此会污染 ksh 的 history 命令历史。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK