原文地址:https://www.lujun9972.win/blog/2021/07/27/aix中的timeout脚本/index.html
AIX 下没有现成的 timeout 命令来限时运行命令,于是就想着自己实现一个类似的脚本。本来以为挺简单的一件事情,结果埋者一堆坑。
最初的结果如下:
#! /usr/bin/ksh waitfor=$1 shift command=$* $command & commandpid=$! (sleep $waitfor;kill $commandpid) & # 坑1 watchdogpid=$! wait $commandpid kill $watchdogpid # 坑2
这里有两个需要关注的地方:
(sleep $waitof;kill $commandpid) &在超时杀掉工作命令后就退出了,工作命令被杀掉之后wait $commandpid执行完成,主进程继续执行kill $watchdogpid. 然而由于监控进程早已退出,在忙碌的系统中,可能出现$watchdogpid被其他进程重复使用,导致误杀其他进程的风险。 要解决这一风险,可以让监控进程在杀掉工作进程后再等待一段时间,以便让主进程杀掉监控进程。kill $watchdogpid在ksh中并不会把子进程一起杀掉,也就是说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 命令历史。
本文介绍在AIX系统中实现timeout功能的过程与遇到的问题。由于AIX系统缺乏现成的timeout命令,作者通过shell脚本实现了命令限时运行的功能,并解决了进程中断后可能引发的误杀风险。
339

被折叠的 条评论
为什么被折叠?



