複数のプログラムを実行するbashスクリプトがあります
#!/bin/sh
python program1.py &
python program2.py &
other programs ... &
lastProgram
私はそれを次のように実行します。./myscript.sh
Ctrl+を押して閉じると終了CしlastProgram
、他のすべてのプログラムはバックグラウンドで実行され続けます。問題は他のプログラムを終了しなければならないという点だ。
스크립트에서 시작된 모든 프로그램의 종료를 올바르게 처리하는 방법은 무엇입니까?
答え1
종료 시 프로세스 ID를 수집하고 백그라운드 프로세스를 종료합니다.
#!/bin/bash
killbg() {
for p in "${pids[@]}" ; do
kill "$p";
done
}
trap killbg EXIT
pids=()
background job 1 &
pids+=($!)
background job 2... &
pids+=($!)
foreground job
EXIT
이유에 관계없이 캡처는 셸이 종료될 때 함수를 실행합니다. trap killbg SIGINT
에서만 변경할 수 있습니다 ^C
.
스크립트가 시작을 시도하기 전에 백그라운드 프로세스 중 하나가 종료되었는지 확인하지 않습니다. 이렇게 하면 실수를 할 수도 있고, 더 심한 경우 잘못된 공정을 촬영하게 될 수도 있습니다.
아니면 직업 ID로 그들을 죽이세요. 출력을 읽고 jobs
어떤 것이 아직 활성 상태인지 알아 보겠습니다.
#!/bin/bash
killjobs() {
for x in $(jobs | awk -F '[][]' '{print $2}' ) ; do
kill %$x
done
}
trap killjobs EXIT
sleep 999 &
sleep 1 &
sleep 999 &
sleep 30
다른 프로세스(예: subshell: )를 생성하는 백그라운드 프로세스를 실행하는 경우 이 프로세스가 제대로 작동하려면 ("모니터 모드")를 사용하여 작업 제어를 활성화 (sleep 1234 ; echo foo) &
해야 합니다 . set -m
그렇지 않으면 부팅 프로세스만 종료됩니다.
答え2
방금 PID 수집에 대한 비슷한 질문을 읽었고 스크립트 끝에서 PID를 종료했습니다.질문완료된 프로세스의 PID입니다.새로운 공정에서 재활용 및 재사용 가능스크립트가 완료되기 전에 다음을 수행할 수 있습니다.새로운 (임의) 프로세스 종료.
bash의 작업 제어를 사용하여 EXIT를 포착하고 종료하세요.
bash의 작업 제어를 사용하면 트랩과 %n jobspec을 사용하여 스크립트에서 시작된 프로세스만 종료하여 실행할 수 있는 최대 작업 수를 계산할 수 있습니다(이 예에서는 3개만).
#!/bin/bash
#trap 'kill %1 %2 %3' 0 # 0 or EXIT are equivalent
#trap 'kill %1 %2 %3' EXIT # or use {1..n} as below
trap 'kill %{1..3}' EXIT
sleep 33 &
sleep 33 &
sleep 33 &
echo processes are running, ctrl-c the next sleep
sleep 66
echo this line will never be executed
이미 완료된 존재하지 않는 작업 사양을 추가로 "종료"하면 오류 메시지만 나타날 뿐 다른 새로운/무작위 프로세스는 종료되지 않습니다.
스크립트의 전체 프로세스 그룹을 종료합니다.
이는 스크립트의 전체 프로세스 그룹을 종료하는 약간 다른 방법입니다. 그러나 스크립트/셸의 작업 제어가 설정되지 않은 경우할 수 있다상위로부터 PPID를 상속받습니다. 하지만 작업 제어가 없으면 위의 작업도 작동하지 않습니다.
차이점은 트랩의 kill 명령이 bash의 PID를 사용한다는 것입니다. 이는 새 프로세스의 PGID가 되기 때문입니다.
trap 'kill -- -$$' EXIT
바라보다이 관련 질문또는여기서 Johannes는 Ziemke를 "낚아채서" SIGINT 및 SIGTERM을 캡처하고 setsid
"자살 위험이 없도록 새 프로세스 그룹에서 전체 프로세스 그룹을 종료합니다.".)
答え3
실행이 완료되기 전에 완료되지 않은 모든 백그라운드 프로세스를 종료하려면 lastProgram
모든 PID를 저장해야 합니다.
python program1.py &
p1pid=$!
python program2.py &
p2pid=$!
other programs ... &
p3pid=$!
lastProgram
kill $p1pid $p2pid $p3pid
wait
스크립트를 종료하기 전에 모든 백그라운드 프로세스의 실행이 완료될 때까지 기다리려는 경우 이 명령을 사용할 수 있습니다 .
python program1.py &
python program2.py &
other programs ... &
lastProgram
wait
答え4
이것은 내 한 줄 명령입니다( bash
).
trap "jobs -p | xargs kill ; trap - INT" INT ; cmd1 & cmd2 & cmd3 &
# replace `cmds` with your command
그것이 하는 일은 모든 백그라운드 작업을 종료하고 기본 동작으로 되돌리기 위해 Ctrl+를 잡는 것입니다.C
그런 다음 백그라운드에서 모든 명령을 실행합니다.
Ctrl+ 를 클릭하면 C모든 트랩이 종료되고 트랩이 기본 동작으로 재설정됩니다.