Bash 스크립트에서 여러 서브루틴을 시작한 다음 기다리려고 합니다.누구나다른 하나를 종료하고 스크립트를 종료하기 전에 하나를 종료하십시오.
CMD1PID= CMD2PID= 출구트랩() { echo "트랩 종료: 작업 종료..." sudo kill $CMD1PID $CMD2PID 출구 } 세트비엠 트랩 종료_트랩 종료 INT 용어 sudo cmd1 --args & CMD1PID=$? sudo cmd2 --args & CMD2PID=$? $CMD1PID $CMD2PID를 기다립니다.
(참고로 GNU bash, version 4.2.37(1)-release (arm-unknown-linux-gnueabi)
Debian Weezy에 있습니다)
불행히도 이것은 제대로 작동하지 않는 것 같습니다. 나는 다음과 같은 여러 가지 변형을 시도했습니다.
- 명령 주위에 중괄호를 사용한 다음 쉘 프로세스를 명시적으로 종료합니다. 즉,
{ cmd1 --args ; kill -USR1 $$ ; } &
유사한 프로세스를 종료한 다음 USR1을 캡처합니다. kill 0
종료 시 여전히 실행 중인 명령을 종료 하는 데 사용됩니다.- 함정 - 단점은
CHLD
필요한 경우 명령 간에 전환할 수 없다는 것입니다. 결국 전환해야 할 수도 있습니다.sleep
...하지만 제가 자주 직면하는 문제는 다음과 같습니다.
- 명령 중 하나를 종료해도 상위 Bash 프로세스가 종료되거나 다른 명령이 종료되지 않습니다.
- 상위 Bash 프로세스를 종료해도 두 명령이 모두 종료되지는 않습니다.
아마도 다른 스크립트의 다른 스크립트가 비슷한 스크립트를 사용하여 행운을 누린 것 같기 때문에 sudo를 사용해야 한다는 요구 사항이 나를 방해하는 것 같습니다. Bash에서 하려는 작업을 수행할 수 있는 좋은 방법이 있나요?
답변1
두 가지 문제가 있습니다. 흥미로운 어린이가 언제 끝나는지 결정해야 하고, 모든 어린이를 죽여야 합니다.
첫 번째는 내장된 "대기"를 사용할 수 없다는 의미입니다.모두어린이(또는 목록에 있는 모든 어린이)에게 적합하지 않습니다.어느. USR1을 기반으로 한 귀하의 제안은 EXIT뿐만 아니라 이에 적합합니다.
두 번째는 훨씬 더 어렵습니다. sudo를 사용하고 있기 때문에 실제로 프로세스에 신호를 보낼 권한이 없으며 사용자 ID가 일치해야 하거나 루트여야 합니다.
파일 시스템이나 파일 핸들 기반 신호 또는 이와 유사한 것을 사용해 볼 수 있지만 솔직히 이것은 다른 스크립팅 언어(Python, Perl 등)에서 이해하기 쉽고 읽기 쉽고 유지 관리하기 쉬울 것이며 심지어 너무 복잡할 것입니다. 대상 사용자 아래에서 전체 스크립트를 실행하는 것이 좋습니다.
답변2
UNIX 스타일의 "복잡한 작업을 더 작은 작업으로 나누기"를 제안한다면 sudo 문제를 해결하여 시작하여 더 간단한 "하위 프로세스가 종료될 때 Bash 스크립트 종료" 문제가 남게 됩니다. 아이의 직계 부모.
#!/bin/sh
exec sudo sh -c '
exit_trap() {
kill # pids
}
trap exit_trap SIGNALS
# run children &
wait # pids
'
이 시점에서 스크립트는 기본적으로 작은따옴표로 묶인 내부 스크립트를 둘러싼 sudo 지원 래퍼입니다. 이것이 가치가 있는지는 잘 모르겠지만 exec
sudo 호출(이 경우 제거하려는 경우) 전후에 실행해야 하는 추가 코드로 인해 이 이상한 동작이 가치가 있을 수 있습니다.