하나의 프로세스가 종료되면 나머지 프로세스도 종료될 수 있도록 "프로세스 그룹"에서 여러 터미널 창을 시작합니다.

하나의 프로세스가 종료되면 나머지 프로세스도 종료될 수 있도록 "프로세스 그룹"에서 여러 터미널 창을 시작합니다.

3개의 터미널 에뮬레이터 창을 시작하는 스크립트가 있습니다.

#!/bin/sh

terminator --role='terminator-left' 2>/dev/null &
sleep 0.1
terminator --role='terminator-center' 2>/dev/null &
sleep 0.1
terminator --role='terminator-right' 2>/dev/null &

(저는 openbox 구성 파일에 정의된 다른 모니터에 창을 자동으로 배치할 수 있도록 --role 옵션을 사용합니다)

저는 이 스크립트를 다른 가상 데스크탑에서 여러 번 시작했습니다.

일종의 "프로세스 그룹"에서 이 3개의 터미널을 시작하여 그 중 하나가 종료되면 나머지 모든 프로세스가 종료될 수 있도록 하려면 어떻게 해야 합니까?

중요: 스크립트의 다른 인스턴스에서 시작될 수 있는 모든 터미널을 종료하고 싶지는 않습니다. 패턴과 일치하는 프로세스를 종료하기 위해 pkill 또는 pgrep을 사용할 수는 없습니다.

즉, 가상 데스크톱 1과 가상 데스크톱 2에서 스크립트를 실행한다고 가정해 보겠습니다.

이제 2개의 서로 다른 가상 데스크톱에 3개의 터미널 창이 있습니다.

가상 데스크톱 1에서 터미널을 종료할 때 가상 데스크톱 2에서 실행 중인 다른 3개의 개별 창 인스턴스에 영향을 주지 않고 나머지 2개의 창이 자동으로 종료되기를 원합니다.

내가 설명하는 것이 가능합니까?

어떻게 해야 하나요?

답변1

부인 성명:
나는 openbox에서 내 제안을 테스트할 기회가 없었습니다. kde-plasma에서만 확인했습니다.
내 솔루션은 wait쉘 내부 명령 에 의존합니다.POSIX 프로그래머 매뉴얼에 명시된 바와 같이. 특정 구현에서는 -n 옵션을 사용하여 스크립트를 더 간단하게 만들 수 있습니다.


#!/bin/sh

ownkill()
{
        trap - CHLD
        pkill --signal 15 -P $$ 
}

terminator --role='terminator-left' 2>/dev/null &
sleep 0.1
terminator --role='terminator-center' 2>/dev/null &
sleep 0.1
terminator --role='terminator-right' 2>/dev/null &
trap ownkill CHLD
wait

이 스크립트는 다음 아이디어를 기반으로 합니다.

  1. 시작 3터미네이터필요에 따라 처리하고,
  2. 완료될 때까지 기다리세요.
  3. 나머지 프로세스와 동일한 방식으로 위 프로세스 중 하나를 종료하는 SIGCHLD 신호를 처리합니다.

참고 1(리셋 핸들러): aviro가 주석에서 올바르게 관찰한 것처럼 신호 처리기는 SIGCHLD 처리를 기본값으로 재설정해야 합니다. 나머지 프로세스를 종료하면 다른(최대 2개) SIGCHLD가 트리거되기 때문입니다.
그렇게 하지 않으면 쉘은 일종의 재귀 상황(핸들러는 스스로 생성한 신호를 처리해야 함)에 빠지게 되며, 이는 쉘 구현에 따라 어느 정도 적절하게 관리됩니다. (무해한 경고부터 일부최대 재귀 깊이를 초과했습니다.또는 그에 상응하는 것. 실수. )

참고 2(대기할 때까지 SIGCHLD 기본 처리 유지): Martin Vegter가 주석에서 올바르게 관찰했듯이 이 trap ownkill CHLD명령은 대기 명령 바로 앞에 배치되어야 합니다.
이것을 스크립트의 첫 번째 명령으로 만들면(이전 버전에서 터무니없이 제안한 것처럼) sleep첫 번째 프로세스가 종료되자마자 전용 핸들러가 트리거됩니다.

답변2

wait -nBash를 사용하면 모든 프로세스 ID를 간단히 수집하고 프로세스가 종료될 때(bash의 경우 ) 모든 ID가 적절한 신호에 의해 종료 되도록 마지막에 기다릴 수 있습니다 .

#!/bin/bash
terminator --role='terminator-left' 2>/dev/null &
pid1=$!
sleep 0.1
terminator --role='terminator-center' 2>/dev/null &
pid2=$!
sleep 0.1
terminator --role='terminator-right' 2>/dev/null &
pid3=$!
wait -n
kill -hup $pid1 $pid2 $pid3 2>/dev/null

PID 중 하나가 만료되었으므로 kill오류 메시지를 피하기 위해 stderr을 null로 리디렉션합니다.

답변3

시작, 제어 및 중지가 간단하기 때문에 systemd 임시 장치를 기꺼이 사용할 수 있습니다. 쉘 스크립트가 다음과 같다고 가정하고 즉시 완료되지 않도록 끝에 명령을 ./myscript추가한 후 다음을 사용하여 시작할 수 있습니다.wait -n

systemd-run --user --unit=mytest1 ./myscript

이 명령은 즉시 메시지를 반환하며 Running as unit: mytest1.service일반 명령을 사용하여 생성한 임시 셀에서 어떤 프로세스가 실행되고 있는지 확인할 수 있습니다.

systemctl status --user mytest1

하나의 명령으로 모든 프로세스를 중지할 수 있습니다.

systemctl stop --user mytest1

--unit=동일한 스크립트를 여러 번 실행하려면 매번 다른 이름을 사용해야 합니다 . 모두 로 시작하는 경우 test모두 확인하거나 로 참조하여 중지할 수 있습니다 test*.

바라보다남자 시스템 실행--setenv=, --working-directory=, 등 유용할 수 있는 다양한 옵션에 대해 알아보세요 --collect. --wait명령 끝에서 스크립트에 인수를 전달할 수도 있습니다 systemd-run.

관련 정보