터미널 명령 이외의 다른 방법으로 닫히지 않는 X 창을 만드는 방법

터미널 명령 이외의 다른 방법으로 닫히지 않는 X 창을 만드는 방법

나는 X11에서 시작하여 내 사용자가 종료할 수 없는 그래픽 프로세스를 생성하려고 합니다.

보다 구체적으로 말하면 부팅 시 시작되고 즉시 tmux 세션을 실행하는 urxvt 드롭다운 터미널이 있습니다. 나를 짜증나게 하는 것은 때때로 Alt그것이 드롭다운 터미널이라는 것을 잊고 숨겨야 할 때 +를 사용하여 그것을 죽인다는 것입니다.F4

물론 다른 터미널에서 다시 연결할 수 있기 때문에 tmux 세션을 잃지는 않지만 드롭 터미널을 (정확한 구성으로) 다시 시작하고 다시 연결해야 하니 지루합니다.

내가 하고 싶은 일은 이 특정 프로세스를 Alt종료 할 수 없습니다 .F4.

이 기사를 읽은 후: Linux에서 프로세스를 종료 불가능하게 만들기

나는 다른 사용자에게 속한 프로세스를 시작해야 한다는 것을 알고 있지만 내 X 서버에서도 이 작업을 수행할 수 있습니다.

    sudo xhost +local:
    sudo runuser -l my-secondary-user -c urxvt

저는 두 가지 나쁜 행동에 직면해 있습니다.

  1. 내 주 사용자(X 세션을 소유한 사용자)가 프로세스를 종료할 수 있습니다.
  2. 가상 터미널은 (물론) 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

그 외에도 메뉴 모음에서, 색조 패널을 마우스 오른쪽 버튼으로 클릭하거나 명령을 통해 필요한 모든 항목을 제거할 수 있습니다. 그러나 이 접근 방식은 다음을 의미합니다.

  1. Tint2 패널을 마우스 오른쪽 버튼으로 클릭하여 드롭 터미널을 종료할 수 있습니다. (드롭 터미널이 패널에 아이콘으로 표시되지 않도록 하면 문제가 해결될 수 있습니다. 연구를 통해 가능할 것입니다.)
  2. Alt+ 다른 터미널 창을 사용할 수 없습니다 F4(별로 마음에 들지는 않지만 허용될 수도 있음).

어떤 아이디어가 있나요?

답변1

xterm전환할 수 있는 옵션이 있는 경우 아래 트릭을 사용할 수 있습니다. 그러나 몇 가지 주의 사항이 있습니다. 이들 중 대부분이 해결되면 솔루션이 상당히 복잡해집니다. 마지막에 있는 최종 스크립트를 참조하세요.

xterm -e 'trap "" HUP; your-application'

창 관리자로부터 종료 명령을 받은 후 xtermSIGHUP은 애플리케이션의 프로세스 그룹으로 전송되고 프로세스가 반환될 때만 종료됩니다.

귀하의 애플리케이션이 SIGHUP 핸들러를 재설정하지 않고 애플리케이션의 하위 애플리케이션에 원치 않는 부작용이 있을 수 있다고 가정합니다.

귀하의 응용 프로그램이 tmux.

이러한 문제를 해결하려면 다음을 수행할 수 있습니다.

xterm -e sh -c 'bash -mc tmux <&1 & trap "" HUP; wait'

이렇게 하면 tmux다른 프로세스 그룹에서 시작되므로 shSIGHUP만 수신되고 무시됩니다.

이제 이는 이러한 신호에 대한 핸들러를 재설정하는 데 적용되지 않지만 tmux일반적으로 구현에 따라 shSIGINT, SIGQUIT 신호는 bash비대화형 신호로 제공되므로 일반적으로 애플리케이션에서 무시됩니다 sh. 귀하가 귀하의 응용 프로그램을 사용 Ctrl+C하거나 중단하는 것을 방지합니다 Ctrl+\.

이는 POSIX 요구 사항입니다. 일부 쉘은 mksh이를 지원하지 않거나(적어도 현재 버전은 아님) dashSIGINT를 부분적으로만 지원하고 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또 다른 질문은 다른 이유로 사라지는 경우입니다 .폐쇄예를 들어 xtermX 서버에 대한 연결이 종료되거나 끊어진 경우(예 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

질문 작성자는 다음과 같은 해결책을 제시합니다.

나에게 맞는 솔루션을 찾았습니다.드미트리의 답변위의 편집 내용은 다음과 같습니다.

  1. 내 맞춤 제목을 설정했습니다 urxvt.
urxvt -title urxvt-drop-down

다음과 같기 때문에 맞춤 이름을 사용하지 않았습니다.

urxvt -name urxvt-drop-down

.Xresources이 명령은 현재 사용 중인 파일을 무시 하고 -title대신 사용합니다.

  1. 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>
  1. 범인이 작업 표시줄에 표시되지 않도록 하고 skip_taskbar창의 초점도 흐려지기 때문에 다시 초점을 맞췄습니다. rc.xml:
   <application title="urxvt-drop-down">
     <skip_taskbar>yes</skip_taskbar>
     <focus>yes</focus>
   </application>

이것이 문제를 해결했지만 본질적으로 해결 방법입니다. 그래서 아직은 잘 모르겠지만스티븐의 대답이 질문에 대한 정답입니다.

수행 중인 작업을 이해하려면 제공된 명령에 대한 일부 연구가 필요합니다.

하지만 나는 그것을 사용하지 않을 것입니다 xterm. 왜냐하면 나는 가짜 투명도와 드롭다운 기능을 원하기 때문입니다(내 생각에는 xterm에도 일종의 드롭다운 기능이 있을 수 있다고 생각하지만 투명도는 컴포지터 없이는 확실히 불가능합니다. 그리고 컴포지터를 사용하지 않을 것입니다) ).

관련 정보