Yia*_*los 6 openbox terminal x11
我正在尝试创建一个从 X11 开始的进程,它将是图形化的并且无法被我自己的用户杀死。
更具体地说,我有一个 urxvt 下拉终端,它在启动时开始并立即运行 tmux 会话。令我烦恼的是,当我忘记它是下拉终端并且我应该将其隐藏时,有时我会用Alt+杀死它F4。
当然,我不会丢失我的 tmux 会话,因为我可以从另一个终端重新连接到它,但是我必须重新启动下拉终端(使用确切的配置)并重新连接,这很乏味。
我想做的是不能Alt+F4 杀死这个特定的进程。
阅读本文后: 在 Linux 上使进程不可终止
我知道我应该启动属于另一个用户的进程,但即使我设法在我自己的 X 服务器中执行以下操作:
sudo xhost +local:
sudo runuser -l my-secondary-user -c urxvt
Run Code Online (Sandbox Code Playgroud)
我面临两种不受欢迎的行为:
(2) 可能是可纠正的 - 只需运行一个命令以我的主用户身份登录 - 但我不知道如何修复 (1)。
有没有办法让这项工作,或另一种方式做我想做的事?如果可能的话,我宁愿避免创建内核模块。
使用 Openbox 运行 Arch Linux。
编辑
我想我也许可以让Alt+F4不适用于这个特定的窗口。发现这个: Openbox:在每个应用程序的基础上禁用 Alt-F4
并修改了我的rc.xml:
<keybind key="A-F4">
<action name="If">
<application class="URxvt"
title="tmux-session">
</application>
<then><!-- Do nothing for urxvt-tmux-session --></then>
<else>
<action name="Close" />
</else>
</action>
</keybind>
Run Code Online (Sandbox Code Playgroud)
这比以前稍微好一点:我不能Alt+F4那个终端,但现在也不能Alt+F4任何urxvt窗口。(猜猜这是因为新的 urxvt 窗口都在同一个类名下运行?)
除此之外,我可以从菜单栏中删除我需要的所有内容,或者右键单击我的色调面板,或者,当然,通过命令。但这种方法意味着:
有任何想法吗?
如果切换到xterm是一个选项,您可以使用下面的 hack。不过有一些注意事项。一旦您解决了其中的大部分问题,解决方案就会变得非常复杂,请参阅最后的最终脚本。
xterm -e 'trap "" HUP; your-application'
Run Code Online (Sandbox Code Playgroud)
收到来自窗口管理器的关闭指令后,xterm将向您的应用程序的进程组发送一个 SIGHUP,并且只有在进程返回时才退出自身。
这假设您的应用程序不会重置 SIGHUP 的处理程序,并且可能会对您的应用程序的子级产生不必要的副作用。
如果您的应用程序是tmux.
要解决这些问题,您可以执行以下操作:
xterm -e sh -c 'bash -mc tmux <&1 & trap "" HUP; wait'
Run Code Online (Sandbox Code Playgroud)
这样,tmux将在不同的进程组中启动,因此只有sh会收到 SIGHUP(并忽略它)。
现在,tmux无论如何这并不适用于重置这些信号的处理程序,但在一般情况下,根据您的实现sh,SIGINT、SIGQUIT 信号和通常两者都将被您的应用程序忽略,因为它bash是作为启动的来自非交互式sh. 这意味着您不能使用Ctrl+C或中断您的应用程序Ctrl+\。
这是 POSIX 的要求。一些 shellmksh不尊重它(至少不是当前版本),或者只是部分地像dashSIGINT 而不是 SIGQUIT。因此,如果mksh可用,您可以执行以下操作:
xterm -e mksh -c 'bash -mc your-application <&1 & trap "" HUP; wait'
Run Code Online (Sandbox Code Playgroud)
(尽管mksh如果他们决定修复该不符合项,这可能在未来版本中不起作用)。
或者,如果您不能保证mksh或bash将可用,或者不想依赖将来可能会改变的行为,您可以手动完成他们的工作perl,例如编写一个unclosable-xterm包装脚本,例如:
#! /bin/sh -
[ "$#" -gt 0 ] || set -- "${SHELL:-/bin/sh}"
exec xterm -e perl -MPOSIX -e '
$pid = fork;
if ($pid == 0) {
setpgrp or die "setpgrp: $!";
tcsetpgrp(0,getpid) or die "tcsetpgrp: $!";
exec @ARGV;
die "exec: $!";
}
die "fork: $!" if $pid < 0;
$SIG{HUP} = "IGNORE";
waitpid(-1,WUNTRACED)' "$@"
Run Code Online (Sandbox Code Playgroud)
(称为unclosable-xterm your-application and its args)。
现在,另一个副作用是我们正在创建并放在前台的新进程组(使用bash -m或setpgrp+tcsetpgrp以上)不再是会话领导进程组,因此不再是孤立的进程组(据说现在有一个父进程在照顾它(sh或perl))。
这意味着按下 后Ctrl+Z,该过程将暂停。在这里,我们粗心的父进程将退出,这意味着进程组将收到 SIGHUP(并希望死亡)。
为避免这种情况,我们可以忽略子进程中的 SIGTSTP,但是如果您的应用程序是交互式 shell,对于某些实现,例如mksh, yashor rc,Ctrl-Z对于它们运行的作业也不起作用。
或者我们可以实现一个更仔细的父级,每次停止时恢复子级,例如:
#! /bin/sh -
[ "$#" -gt 0 ] || set -- "${SHELL:-/bin/sh}"
exec xterm -e perl -MPOSIX -e '
$pid = fork;
if ($pid == 0) {
setpgrp or die "setpgrp: $!";
tcsetpgrp(0,getpid) or die "tcsetpgrp: $!";
exec @ARGV;
die "exec: $!";
}
die "fork: $!" if $pid < 0;
$SIG{HUP} = "IGNORE";
while (waitpid(-1,WUNTRACED) > 0 && WIFSTOPPED(${^CHILD_ERROR_NATIVE})) {
kill "CONT", -$pid;
}' "$@"
Run Code Online (Sandbox Code Playgroud)
另一个问题是,如果xterm不是因为关闭窗口管理器的其他原因而消失,例如,如果xterm被杀死或失去与 X 服务器的连接(例如,由于Window 管理器xkill的销毁操作,或者 X 服务器崩溃) ),那么这些进程不会死亡,因为在这些情况下也会使用 SIGHUP 来终止它们。要解决这个问题,您可以poll()在终端设备上使用(它会在运行时被拆除xterm):
#! /bin/sh -
[ "$#" -gt 0 ] || set -- "${SHELL:-/bin/sh}"
exec xterm -e perl -w -MPOSIX -MIO::Poll -e '
$pid = fork; # start the command in a child process
if ($pid == 0) {
setpgrp or die "setpgrp: $!"; # new process group
tcsetpgrp(0,getpid) or die "tcsetpgrp: $!"; # in foreground
exec @ARGV;
die "exec: $!";
}
die "fork: $!" if $pid < 0;
$SIG{HUP} = "IGNORE"; # ignore SIGHUP in the parent
$SIG{CHLD} = sub {
if (waitpid(-1,WUNTRACED) == $pid) {
if (WIFSTOPPED(${^CHILD_ERROR_NATIVE})) {
# resume the process when stopped
# we may want to do that only for SIGTSTP though
kill "CONT", -$pid;
} else {
# exit when the process dies
exit;
}
}
};
# watch for terminal hang-up
$p = IO::Poll->new;
$p->mask(STDIN, POLLERR);
while ($p->poll <= 0 || $p->events(STDIN) & POLLHUP == 0) {};
kill "HUP", -$pid;
' "$@"
Run Code Online (Sandbox Code Playgroud)