나는 X11에서 시작하여 내 사용자가 종료할 수 없는 그래픽 프로세스를 생성하려고 합니다.
보다 구체적으로 말하면 부팅 시 시작되고 즉시 tmux 세션을 실행하는 urxvt 드롭다운 터미널이 있습니다. 나를 짜증나게 하는 것은 때때로 Alt그것이 드롭다운 터미널이라는 것을 잊고 숨겨야 할 때 +를 사용하여 그것을 죽인다는 것입니다.F4
물론 다른 터미널에서 다시 연결할 수 있기 때문에 tmux 세션을 잃지는 않지만 드롭 터미널을 (정확한 구성으로) 다시 시작하고 다시 연결해야 하니 지루합니다.
내가 하고 싶은 일은 이 특정 프로세스를 Alt종료 할 수 없습니다 .F4.
이 기사를 읽은 후: Linux에서 프로세스를 종료 불가능하게 만들기
나는 다른 사용자에게 속한 프로세스를 시작해야 한다는 것을 알고 있지만 내 X 서버에서도 이 작업을 수행할 수 있습니다.
sudo xhost +local:
sudo runuser -l my-secondary-user -c urxvt
저는 두 가지 나쁜 행동에 직면해 있습니다.
- 내 주 사용자(X 세션을 소유한 사용자)가 프로세스를 종료할 수 있습니다.
- 가상 터미널은 (물론) my-secondary-user로 로그인을 시작합니다.
(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>
이전보다 약간 나아졌습니다. 터미널을 Alt+ 할 수 없지만 이제는 urxvt 창도 + 할 수 없습니다. (새 urxvt 창이 모두 동일한 클래스 이름으로 실행되기 때문인 것 같나요?)F4AltF4
그 외에도 메뉴 모음에서, 색조 패널을 마우스 오른쪽 버튼으로 클릭하거나 명령을 통해 필요한 모든 항목을 제거할 수 있습니다. 그러나 이 접근 방식은 다음을 의미합니다.
- Tint2 패널을 마우스 오른쪽 버튼으로 클릭하여 드롭 터미널을 종료할 수 있습니다. (드롭 터미널이 패널에 아이콘으로 표시되지 않도록 하면 문제가 해결될 수 있습니다. 연구를 통해 가능할 것입니다.)
- Alt+ 다른 터미널 창을 사용할 수 없습니다 F4(별로 마음에 들지는 않지만 허용될 수도 있음).
어떤 아이디어가 있나요?
답변1
xterm
전환할 수 있는 옵션이 있는 경우 아래 트릭을 사용할 수 있습니다. 그러나 몇 가지 주의 사항이 있습니다. 이들 중 대부분이 해결되면 솔루션이 상당히 복잡해집니다. 마지막에 있는 최종 스크립트를 참조하세요.
xterm -e 'trap "" HUP; your-application'
창 관리자로부터 종료 명령을 받은 후 xterm
SIGHUP은 애플리케이션의 프로세스 그룹으로 전송되고 프로세스가 반환될 때만 종료됩니다.
귀하의 애플리케이션이 SIGHUP 핸들러를 재설정하지 않고 애플리케이션의 하위 애플리케이션에 원치 않는 부작용이 있을 수 있다고 가정합니다.
귀하의 응용 프로그램이 tmux
.
이러한 문제를 해결하려면 다음을 수행할 수 있습니다.
xterm -e sh -c 'bash -mc tmux <&1 & trap "" HUP; wait'
이렇게 하면 tmux
다른 프로세스 그룹에서 시작되므로 sh
SIGHUP만 수신되고 무시됩니다.
이제 이는 이러한 신호에 대한 핸들러를 재설정하는 데 적용되지 않지만 tmux
일반적으로 구현에 따라 sh
SIGINT, SIGQUIT 신호는 bash
비대화형 신호로 제공되므로 일반적으로 애플리케이션에서 무시됩니다 sh
. 귀하가 귀하의 응용 프로그램을 사용 Ctrl+C하거나 중단하는 것을 방지합니다 Ctrl+\.
이는 POSIX 요구 사항입니다. 일부 쉘은 mksh
이를 지원하지 않거나(적어도 현재 버전은 아님) dash
SIGINT를 부분적으로만 지원하고 SIGQUIT는 지원하지 않습니다. 따라서 mksh
가능하다면 다음과 같이 할 수 있습니다.
xterm -e mksh -c 'bash -mc your-application <&1 & trap "" HUP; wait'
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)' "$@"
(라고 불리는 unclosable-xterm your-application and its args
).
이제 또 다른 부작용은 우리가 생성하여 전경에 배치하는 새 프로세스 그룹( bash -m
또는 setpgrp
+ 포함 tcsetpgrp
)이 더 이상 세션 리더 프로세스 그룹이 아니므로 더 이상 그렇지 않다는 것입니다.고아가 된프로세스 그룹(현재 이를 처리하는 상위 프로세스가 있다고 합니다( sh
또는 perl
)).
즉 Ctrl+Z, 을 누르면 프로세스가 일시 중지됩니다. 여기서는 부주의한 상위 프로세스가 종료됩니다. 이는 프로세스 그룹이 SIGHUP을 수신하고 희망적으로 종료됨을 의미합니다.
이를 방지하기 위해 하위 프로세스에서 SIGTSTP를 무시할 수 있지만 애플리케이션이 대화형 셸인 경우 일부 구현(예 mksh
: yash
또는 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;
}' "$@"
xterm
또 다른 질문은 다른 이유로 사라지는 경우입니다 .폐쇄예를 들어 xterm
X 서버에 대한 연결이 종료되거나 끊어진 경우(예 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;
' "$@"
답변2
귀하의 질문에는 연구를 잘못된 방향으로 이끄는 다소 오해의 소지가 있는 제목이 있습니다. 창문을 닫으면 X
,서버는 프로세스를 종료하지 않습니다. 대신 WM_DELETE_WINDOW
프로세스에 메시지를 보낸 다음 프로세스가 종료됩니다. 이 사실은 첫 번째 접근 방식을 망칠 것입니다. 플래그를 설정하더라도 SIGNAL_UNKILLABLE
여전히 끌 수 있습니다.
두 번째 방법은 효과가 있는 것 같습니다. 단일 터미널 창과 다른 모든 창을 구별하기만 하면 됩니다. 이를 달성하는 한 가지 방법은 urxvt
특정 제목(예:)으로 시작하여 urxvt -name urxvt-iddqd
해당 이름에 대한 규칙을 만드는 것입니다.
<keybind key="A-F4">
<action name="If">
<application title="urxvt-iddqd"
title="tmux-session">
</application>
<then><!-- Do nothing for urxvt-tmux-session --></then>
<else>
<action name="Close" />
</else>
</action>
</keybind>
답변3
질문 작성자는 다음과 같은 해결책을 제시합니다.
나에게 맞는 솔루션을 찾았습니다.드미트리의 답변위의 편집 내용은 다음과 같습니다.
- 내 맞춤 제목을 설정했습니다
urxvt
.urxvt -title urxvt-drop-down
다음과 같기 때문에 맞춤 이름을 사용하지 않았습니다.
urxvt -name urxvt-drop-down
.Xresources
이 명령은 현재 사용 중인 파일을 무시 하고-title
대신 사용합니다.
- Alt+ 키 바인딩을 사용하여 F4제목이 붙은 터미널을 무시합니다
urxvt-drop-down
. rc.xml:<keybind key="A-F4"> <action name="If"> <title>urxvt-drop-down</title> <then><!-- Do nothing for urxvt-drop-down --></then> <else> <action name="Close" /> </else> </action> </keybind>
- 범인이 작업 표시줄에 표시되지 않도록 하고
skip_taskbar
창의 초점도 흐려지기 때문에 다시 초점을 맞췄습니다.rc.xml
:<application title="urxvt-drop-down"> <skip_taskbar>yes</skip_taskbar> <focus>yes</focus> </application>
이것이 문제를 해결했지만 본질적으로 해결 방법입니다. 그래서 아직은 잘 모르겠지만스티븐의 대답이 질문에 대한 정답입니다.
수행 중인 작업을 이해하려면 제공된 명령에 대한 일부 연구가 필요합니다.
하지만 나는 그것을 사용하지 않을 것입니다
xterm
. 왜냐하면 나는 가짜 투명도와 드롭다운 기능을 원하기 때문입니다(내 생각에는 xterm에도 일종의 드롭다운 기능이 있을 수 있다고 생각하지만 투명도는 컴포지터 없이는 확실히 불가능합니다. 그리고 컴포지터를 사용하지 않을 것입니다) ).