在Bash中设置子进程的信号掩码

在Bash中设置子进程的信号掩码

这是我的问题 - 我正在尝试编写一个小包装脚本,在调用 Xorg 时添加一个命令行参数(我无权访问调用者的源代码。)它看起来很简单,但我现在运行的问题into 表示调用者正在等待USR1来自 Xorg 的信号。来自 XSERVER 手册页:

SIGUSR1

该信号的使用方式与上述信号完全不同。当服务器启动时,它会检查是否继承了 SIGUSR1 作为 SIG_IGN 而不是通常的 SIG_DFL。在这种情况下,服务器在建立各种连接方案后向其父进程发送 SIGUSR1。 Xdm 使用此功能来识别何时可以连接到服务器。

我想我可以简单地捕获信号并转发它:

#!/bin/bash
parent_trap(){
   echo sending USR1 to $PPID &> /tmp/wrapper.log
   kill -USR1 $PPID
}
trap "parent_trap" USR1
Xorg $@ (extra stuff) &
wait

但当然这是行不通的,因为脚本本身是由调用者忽略USR1.我认为我需要做的是让脚本停止忽略信号,但也要以某种方式启动 Xorg 并USR1忽略(以触发手册页中的行为。)

这在 Bash/其他脚本语言中可能吗?由于一些原因,我希望避免编译解决方案,但这并非不可想象。也有可能我完全认为这是错误的,并且还有其他方法可以USR1从 Xorg 到达调用者。

答案1

你的新脚本

与其尝试对信号做一些奇特的事情,为什么不直接这样做:

$ cat xorg_wrapper
#!/bin/bash

exec Xorg $@ (extra stuff)

怎么运行的

为了说明上面的情况,这里有一个更详细的示例,有助于展示exec上述脚本中的机制。

$ cat xorg.bash
#!/bin/bash

echo "script's PID: $$"
sleep 5
echo "starting fakeXorg..."
exec sleep 5

# Nothing below here will execute due to exec
echo $!
echo "fakeXorg finished..."
sleep 5

这将按照您指定的方式启动 Xorg,但因为我们使用的exec命令Xorg将采用相同的 PID 并xorg.bash用其自身替换我们的脚本。

笔记:上面最后 3 行的目的是证明命令运行xorg.bash后不再播放/运行exec sleep ...

例子

首先我们运行我们的脚本:

$ ./xorg.bash
script's PID: 22471

...5 seconds passes...

starting fakeXorg...

...now the exec runs and 5 more seconds pass...

$

如果我们要在另一个 shell 中使用它来监视它,ps auxf我们会看到这个。

第 1 阶段 - xorg.bash 预执行
$ ps auxf
....
root     21184  0.0  0.3 116596  3412 pts/2    S    20:19   0:00                  \_ /bin/bash
root     22471  0.0  0.1 113176  1400 pts/2    S+   20:43   0:00                      \_ /bin/bash ./xorg.bash
root     22472  0.0  0.0 107948   348 pts/2    S+   20:43   0:00                          \_ sleep 5
第 2 阶段 - xorg.bash 执行后
$ ps auxf
....
root     21184  0.0  0.3 116596  3412 pts/2    S    20:19   0:00                  \_ /bin/bash
root     22471  0.0  0.0 107948   352 pts/2    S+   20:43   0:00                      \_ sleep 5

请注意,在第 1 阶段,xorg.bashPID 为 22471,但在第 2 阶段,exec sleep 5现在具有相同的 PID,22471。

之后的行exec ...

该命令的功能exec导致当前 shell 被另一个可执行文件替换:

   $ help exec
    ...
        Replace the shell with the given command.

因此,任何命令都不会xorg.bash被执行,因为在该点exec ....xorg.bash它不再作为进程存在,已被sleep命令取代。

参考

相关内容