孤儿(ksh Shell 脚本未在 CTRL-X 上首先终止)
Posted
技术标签:
【中文标题】孤儿(ksh Shell 脚本未在 CTRL-X 上首先终止)【英文标题】:Orphan Child (ksh Shell Script not terminating first upon CTRL-X) 【发布时间】:2013-06-22 21:58:03 【问题描述】:我在 AIX 5.3 上有一个启动 Shell 脚本 (ksh) 的程序(C++ 可执行文件)。
当我启动程序和 shell 脚本时,我看到两个进程
AIX:>ps -ef | grep 3657892
u001 **3657892** 3670248 0 18:16:34 pts/11 0:00 /u0012006/bin/Launcher
u001 3723398 **3657892** 0 18:16:41 pts/11 0:00 /usr/bin/ksh /u0012006/shell/Trjt_Slds.sh -m
现在,当我在键盘上按 CTRL-X 组合键以结束并退出 Shell 脚本时,主启动程序(C++ 可执行文件)进程在 shell 脚本继续执行时被终止。
AIX:>ps -ef | grep 3723398
u001 3723398 1 106 18:16:41 pts/11 0:01 /usr/bin/ksh /u0012006/shell/Trjt_Slds.sh -m
u001 3731504 3723398 0 0:00 <defunct>
u001 3735612 3723398 0 0:00 <defunct>
u001 3739838 3723398 0 0:00 <defunct>
这会导致 CPU 消耗达到 100%,并启动许多已失效的进程。
当我执行 CTRL-X 时,有没有办法让 AIX Shell 脚本首先终止?
【问题讨论】:
你能提供一个shell脚本的sn-p代码,或者稍微介绍一下它的作用吗?在某些情况下,简单地使用exec program
可能会通过完全消除 shell 进程来解决该问题。
@RudyMatela 感谢您的意见。不幸的是,用 C++ 编写的 Launcher Program 无法更改。我可以更改脚本。脚本本身在无限循环中运行,询问我从用户那里获得的参数并查询 Oracle DB 并获取结果并向用户显示并继续循环。我在dpaste.com/1271101 粘贴了一个可能感兴趣的 sn-p,这只是 sn-p 的一部分,循环执行我上面指出的操作。
【参考方案1】:
注意:启动器已损坏,应该修复。因此,任何“解决方案”都将是 hack。
一种想法是检查脚本中不同位置的 $PPID。如果设置为 1 (init),则退出脚本。
我不明白 control-X 的用法。这不会产生任何 tty 信号。我想这就是你想要的。也许 tty 也处于原始模式。但是您可能会考虑将 control-X 连接到各种 tty 信号之一,例如 SIGINT。例如stty intr ^X
但您还需要记住使用 stty intr ^C
取消设置
最后,您可以将脚本包装在脚本中并使用该技术杀死孩子并退出。例如(未经测试)
#!/bin/ksh
# launch original program in background
/path/to/real/program "$@" &
# get child's pid
child=$!
while : ; do
# when we become an orphan
if [[ $$PPID -eq 1 ]] ; then
# kill the child and exit
kill $child
exit
fi
# poll once a second
sleep 1
done
更新
./s1 是:
#!/bin/ksh
./s2 &
sleep 10
exit
./s2 是:
#!/bin/ksh
while : ; do
if kill -0 $PPID ; then
echo still good
else
echo orphaned
exit
fi
sleep 1
done
【讨论】:
你总结得很好。我将考虑将 CTRL-X 映射到 SIGINT。我将保存原始期限设置并在退出时恢复。我现在要在我的测试环境中尝试这个。 不幸的是,$PPID 始终保留为原始父进程 ID,并且对于孤立进程不会更改为 1 你是对的......那是最不幸的。我在原始帖子中进行了编辑 嗨 pedz...感谢您的更新。我现在就试试这个。你能告诉我 kill -0 是做什么的吗? 0是特殊信号吗? 我可能弄错了术语,但 kill -0 只是检查进程是否存在。它不发送信号。现在,我不知道它是如何做到的的确切细节。但是您也可以使用 kill 系统调用从 C 代码中执行此操作。 ***.com/questions/11012527/…【参考方案2】:ksh 总是这样做。刚刚被这个咬了,与 bash 不同,ksh 在您退出时不会转发 hup 信号。如果你能找到孩子的 pid,你可以自己动手。
【讨论】:
以上是关于孤儿(ksh Shell 脚本未在 CTRL-X 上首先终止)的主要内容,如果未能解决你的问题,请参考以下文章