我正在查看,这是启动程序的dmenu_run
默认脚本,并看到其中的这一部分引起了我的兴趣:dmenu
[..other stuff..] | dmenu | sh &
所以我做了一些测试。
先决条件信息
我正在运行 GNU/Linux。
sh
在dash
我的系统上。我的登录外壳是bash
.
st
和xterm
是终端模拟器。
替换为测试期间创建的窗口$XTERMPID
的 PID 。xterm
您可以使用xprop
它来获取它。
xterm
似乎不会产生日志输出,除非出现问题。您可以将其替换为另一个实际生成日志输出以执行该部分测试的程序。
测试
场景#1 - 运行xterm
(或xterm &
)st
:
可以看到xterm登录了st
。
pstree -s $XTERMPID
输出:systemd───sddm───sddm-helper───i3───st───bash───xterm───bash
关闭后st
xterm
被杀。
场景#2 - 运行echo xterm | sh
(或echo xterm | sh &
)于st
:
您可以xterm
在 中看到日志st
。
pstree -s $XTERMPID
输出:systemd───sddm───sddm-helper───i3───st───bash───sh───xterm───bash
关闭后st
:
xterm
以某种方式幸存下来(这是我不明白的部分。不是所有的孩子都应该被杀吗?)
pstree -s $XTERMPID
输出:systemd───xterm───bash
场景 #3 - 运行setsid -f xterm
于st
:
你不能请参阅xterm
中的日志st
。
pstree -s $XTERMPID
输出:systemd───xterm───bash
关闭后st
:
与预期一致。
场景#4 - 运行echo "echo xterm | sh" | sh
(或echo "echo xterm | sh &" | sh &
)于st
:
你可以仍然查看xterm
日志st
,但xterm
它不再是 的子项st
。我也不明白这个。
pstree -s $XTERMPID
输出:systemd───sh───xterm───bash
关闭后st
:
与预期一致。
问题:
- 当
st
在场景 #2 中被杀死时,为什么xterm
当其父级sh
被杀死时不会被杀死? - 是它
st
还是内核害死了孩子们? - 它只会杀死直系孩子吗?那么为什么当你关闭终端时,在终端 shell 中运行的程序就会死掉呢?
- 为什么在场景 #4 中,即使不是 的子项,
xterm
仍显示的输出?这是如何运作的?st
xterm
st
测试#2
(echo "echo xterm | sh &" | sh &) >/dev/null 2>&1
从i3blocks
脚本运行
一直有效,直到您重新启动 i3i3-msg restart
或 Super+Shift+R。窗口仍然存在,但实际进程将被终止,窗口将充满黑色。
请参阅此错误报告以获取更多详细信息:https://github.com/vivien/i3blocks/issues/483
setsid -f xterm
从i3blocks
脚本运行
工作没有问题
问题:
- 有什么额外的事情可以
setsid -f
做而双管道sh
却不能做?当它们看起来与 相同时,为什么setsid -f
在该i3blocks
场景中起作用而不是在另一个场景中起作用pstree
? setsid
似乎是一个仅限 Linux 的命令,如何仅使用 POSIX 兼容的 shell 和 coreutils 复制它?- 如果进程死亡,为什么窗口仍然可见?