您的位置:首页 > 运维架构 > Shell

对shell脚本Ctrl+C导致被脚本启动的进程全部中断退出

2015-04-16 10:40 471 查看
1.最近接到多位同事反馈,有一台公司内部测试用的服务器平台总是客户端登陆不上,

ssh远程登陆上去发现,有一个基础服务进程停掉了,导致其它依赖该服务的业务进程被无限重启.

一直没找到原因,以致对我们以为服务器软件一定有Bug,甚至对其它已经发布出去服务器的稳定性开始担心.

对模块二进制文件做MD5校验发现有几个bin文件分别被同事们测试时手动替换过,所以就从这几个改动的地方开始调查,即模块编译版本不一致;

只好用最笨的方法,

(1)对所有人的SVN提交作代码审查

(2)对更新的模块做单体测试.

均没有找到原因.只好把问题暂且放下,通过手动重启服务器软件暂时使服务器恢复正常.

2.正常运行一个星期后,上午又有同事报告服务器问题再现.

进紧查看运行日志LOG,发现在上午8点50分左右服务器软件被重启过.

经过询问是一个负责维护的新同事在上午调用自己写的脚本清理服务器并重启,他表未自己当时重启服务器是成功的.

而我根据日志的记录来看,服务器当时重启并未成功,仅正常运行大约2分钟就开始重现上述问题.

因此断定该同事并未仔细验证自己重启是否成功,同事也承认验证不够仔细.

于是我开始找到他写的脚本自己尝试.

该脚本主要做了两件事:

(1)循环检查存储空间,而且是个死循环

(2)一旦判断存储空间不足,就停止服务器软件并删除录像,然后再重启服务器软件.

重启进程是放入后台运行的,即 #`./server &` 这样的形式.

经过仔细阅读脚本,没有发现任务问题,于是开始运行查看效果

#./myclear.sh

执行后发现存储目录被清空,同时服务器开始重启,然后重启成功.

然后此后该脚本开始一直死循环检查存储并打印输出剩余空间.

在此期间我一直查看日志输出,并用客户端登陆进行业务操作一切正常

然而当我以为重启成功退出脚本循环Ctrl+C时,日志窗口立刻显示服务器进程退出.

这时问题原因似乎比较明确了:

对./myclear.sh循环执行窗口按下Ctrl+C的时候,在myclear.sh脚本中启动的所有进程都收到SIGTERM信号并退出了.

即便该进程可执行文件在启动时是放入后台执行的.

3.于是我把问题现象反馈给同事,让他自己进行验证,进一步得出结论:

(1)shell脚本运行时,会产生一个进程组,并且脚本就是这个进程组的组长,

按下Ctrl+C后会导致这个进程组内的进程都收到SIGTERM信号;

而如果换成通过kill向组长进程发信号,则其它子进程不会收到SIGTERM信号.

(2)不局限于shell脚本,对于其它编译程序运行时,如果会fork()多个子进程,其道理也是一样.

这个技术细节原理,等我有时间调查清楚,再单独另写一篇技术性强的文章进行说明.本文章的真正目的在于总结经验教训.

4.问题总结:

(1)每个人都很要强,好面子,就像双刃剑有好处也有坏处

尤其是刚入职的新人,由于害怕丢面子或担责任等原因,在描述问题时,总是容易隐藏掉一些细节和事实.

到了测试和调查问题手里,一些真正有价值的信息恰恰被过滤掉了.

事实上,在服务器第一次出现问题时,我就询问过该同事是否在服务器执行过什么脚本或操作,他回答没有;

直到问题调查出来再问他,又说'可能有,我忘了'.后来我通过history查看历史命令,证明第一次出问题就是那个执行脚本引起的.白白耽误好多时间.

事实上我们对问题一直很宽容的,有问题不怕,怕的是不调查不总结.在同一个问题上一再糊涂.

(2)问题如果重要程度不高,并且不好重现或实在调查不出来,最好就此打住,缓一段时间等待重现.

把宝贵的时间用在其它优先级更高的任务上.把项目进度风险降到最低.

(3)手脑并用,实践出真知,只会抬扛是没有用的.

当把很多问题交给新人去调查的时候,有人只会长时间盯着屏幕发呆,自言自语'怎么可能,这是怎么回事?'最后往往又把问题丢回给我.

我通常问以下几个问题:

(1)看LOG了么?日志上怎么说?

(2)你自己动手尝试问题再现了么?

(3)有疑问的地方去找反馈的人交流了么?

(4)需要其他人配合做什么就提出来

如果回答都是否,就需要注意了,差距就是在这些细节中慢慢拉开的.

即便问题到最后解决不了至少也能给出一种合理的解释,证明你的思考和调查过程,这也是值得表扬的,

毕竟我们调查付出了的时间和精力,就不要让它毫无结果,含混的不了了之.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: