孤儿(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 上首先终止)的主要内容,如果未能解决你的问题,请参考以下文章

在 AIX 上运行 Linux Shell

使用 AIX 的 ksh 实现以非交互模式读取配置文件脚本

shell脚本

如何判断字符串是不是未在 Bash shell 脚本中定义

关于Linux shell,还有bash

linux12shell编程 -->信号控制