当特定的子进程终止时,如何在bash脚本中接收通知



我想知道是否有人能帮上忙?

我有一个bash脚本。它启动一个子进程,这是另一个基于gui的应用程序。bash脚本然后进入交互模式,从用户那里获得输入。这种互动模式一直持续下去。我希望它在子进程中的gui应用程序退出时终止。

我看过SIGCHLD,但这似乎不是答案。这是我试过的,但节目结束时我没有收到信号。

set -o monitor
"${prog}" &
prog_pid=$!
function check_pid {
kill -0 $1 2> /dev/null
}
function cleanup {
### does cleanup stuff here
exit
}

function sigchld {
check_pid $prog_pid
[[ $? == 1 ]] && cleanup
}
trap sigchld SIGCHLD

更新了以下答案我现在使用"nosid"的建议来处理这个问题。我现在有另一个相关的问题,那就是接下来的交互过程是一个基本的菜单驱动过程,它会阻止等待用户的键输入。如果子进程结束,则直到接收到输入之后才处理USR1信号。有什么方法可以强制立即处理信号吗?

等待的样子是这样的:

stty raw                 # set the tty driver to raw mode 
max=$1                   # maximum valid choice
choice=$(expr $max + 1)  # invalid choice
while [[ $choice -gt $max ]]; do
choice=`dd if=/dev/tty bs=1 count=1 2>/dev/null`
done
stty sane                # restore tty

更新了解决方案。我已经解决了这个问题。诀窍是使用非阻塞I/O进行读取。现在,有了"nosid"的答案和我的修改,我得到了我想要的。为了完整起见,以下是对我有效的:

#!/bin/bash -bm
{
"${1}"
kill -USR1 $$
} &
function cleanup {
# cleanup stuff
exit
}
trap cleanup SIGUSR1
while true ; do
stty raw                 # set the tty driver to raw mode 
max=9                    # maximum valid choice
while [[ $choice -gt $max || -z $choice ]]; do
choice=`dd iflag=nonblock if=/dev/tty bs=1 count=1 2>/dev/null`
done
stty sane                # restore tty
# process choice       
done

这里有一种不同的方法。您可以在GUI应用程序终止后立即执行任意命令,而不是使用SIGCHLD。

{
some_command args...
kill -USR1 $$
} &
function sigusr1() { ... }
trap sigusr1 SIGUSR1

好的。我想我明白你需要什么。看看我的。xinitrc:

xrdb ~/.Xdefaults
source ~/.xinitrc.hw.settings
xcompmgr &
xscreensaver &
# after starting some arbitrary crap we want to start the main gui.       
startfluxbox &  PIDOFAPP=$! ## THIS IS THE IMPORTANT PART
setxkbmap genja
wmclockmon -bl &

sleep 1
wmctrl -s 3  && aterms sone &
sleep 1
wmctrl -s 0

wait $PIDOFAPP ## THIS IS THE SECOND PART OF THE IMPORTANT PART
xeyes -geometry 400x400+500+400 &
sleep 2
echo im out!

发生的情况是,在您将进程发送到后台后,您可以使用wait来等待,直到进程终止。只要应用程序正在运行,等待之后的任何内容都不会执行。您可以在GUI关闭后使用此选项退出。

附言:我跑bash。

我认为你需要做:

set -bm

set -o monitor notify

根据bash手册:

-b
Cause the status of terminated background jobs to be reported immediately, rather than before printing the next primary prompt.

shell的主要工作是执行子进程它需要捕获SIGCHLD以达到自己的目的。这在某种程度上限制了它将信号传递给脚本本身。

你能不能检查一下孩子pid,然后根据它发送警报。您可以在下面找到子pid-

bash_pid=$$
while true
do
children=`ps -eo ppid | grep -w $bash_pid`
if [ -z "$children" ]; then
cleanup
alert
exit
fi
done

最新更新