백그라운드에서 실행 중인 프로세스를 중지했다가 다시 시작하는 스크립트가 있습니다.
process_id=`ps -eaf | grep -i daemon | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`
(kill -STOP $process_id) &
... # do something else
(kill -CONT $process_id) &
이것은 잘 작동하지만 STDOUT/STDERR에서 다음을 얻습니다.
[1] + 8545 Suspended (signal) /etc/init.d/...
지금까지 나는 다음을 시도했습니다.
(kill -STOP $process_id)
(kill -STOP $process_id) & > /dev/null
/etc/init.d/{name_of_the_daemon} start > /dev/null
(kill -STOP $process_id & ) 2>/dev/null
(kill -STOP $process_id & disown;) 2>/dev/null
set +m
(kill -STOP $process_id) &
(kill -STOP $process_id) & 1>&2
제가 수행하는 단계는 다음과 같습니다.
- fff 파일 생성
/etc/init.d/
- 아래 스크립트를 붙여넣으세요.
chmod 755 fff
- /etc/init.d/fff 시작
그 후 '일시 중지' 메시지가 표시됩니다.
@sourcejedi에 따르면 내 스크립트는 데몬이 아닙니다. 스크립트의 하위 프로세스가 일시 중지되면 "중지" 메시지가 나타납니다.
셸에 출력되는 특정 메시지만 표시하지 않으려면 어떻게 해야 합니까?
내 스크립트의 매우 간단한 버전은 다음과 같습니다.
#!/bin/bash
pid_script=`ps -eaf | grep -i fff | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`
case "$1" in
start)
( sleep 3; kill -STOP $pid_script ) &
sleep 10;
(sleep 1; kill -CONT $pid_script) &
;;
stop)
for p in $pid_script # kill all the other processes related with this script (if any)
do
kill -9 $p
done
esac
답변1
이 가 표시되면 [1] + 7766 Suspended (signal) ...
이는 하위 프로세스 중 하나가 일시 중지되었음을 알리는 쉘에 의해 인쇄되는 메시지입니다.
이 예 에서는 fff
두 가지 셸 프로세스를 고려해야 합니다. 초기 대화형 셸과 하위 프로세스로 실행되는 셸 스크립트입니다.
스크립트가 자체적으로 중단되도록 준비합니다. 대화형 쉘은 "hang" 메시지를 인쇄합니다. 그래서 켜거나 끌 수 있는 옵션이 아닙니다.스크립트 내부.
또한 대화형 셸에서 옵션을 설정하여 이 특정 메시지를 켜거나 끌 수 없습니다. 이 메시지만으로는 "억제"하는 것이 불가능합니다... 기본적으로 그것은 결코 당신이 하고 싶은 일이 아니기 때문입니다 :-).
fff
어쨌든 스크립트가 성공적으로 자체 복원될 수 있다고 생각하지 않습니다 . 나는 이것을 달성하기 위해 수정될 수 있다고 생각합니다. 그러나 회복 자체는 나쁜 생각입니다. 스크립트를 일시 중지하면 대화형 셸에 명령 프롬프트가 다시 표시됩니다. 즉, "일시 중지" 메시지가 표시되지 않으면 스크립트가 완료된 것 같습니다. 그러나 어느 쪽이든 스크립트가 자체적으로 복구되면 사용자가 그 동안 무엇을 시작하든 관계없이 사용자로부터 터미널 제어권을 되찾으려고 시도합니다. 아주 좋은하지!
예를 들어 터미널에서 프로세스를 시작했는데 이것이대화형 쉘 하위 프로세스그렇다면 그것은 확실히악마프로세스.
시작하다악마터미널에서 프로그램은 시작하는 동안 자체적으로 fork()해야 합니다. 원래 프로세스가 종료되어야 실행 중인 프로세스가 계속됩니다.재육아예를 들어 (기존 유닉스에서는) PID 1 일명 process 입니다 init
. 또한 터미널에서 분리하기 위한 추가 단계도 포함해야 합니다. 여기에서 예를 참조하세요.쉘에서 프로세스를 데몬화합니까?
또한 시스템에서 를 사용하는 경우 부팅하려면 레거시 스크립트를 사용해야 한다는 점을 systemd
이해해야 합니다 . 데비안과 다른 곳의 패키징 스크립트에는 이를 수행하는 호환성 핵이 포함되어 있습니다. 하지만 넌 그래야 해/etc/init.d/
systemctl start
init.d
아니요이 기능을 사용하세요. 이것은 혼돈의 비결입니다. 작성하신 스크립트에는 이 기능이 없으므로~ 해야 하다사용 systemctl start fff
.
fff
스크립트 의 게임을 systemctl start
.
실제로 systemctl
백그라운드 서비스 프로세스를 시작하는 데 사용되는 방법은 다양합니다. systemd
요청된 프로그램을 시작하는 PID 1(init 프로세스)에 메시지를 보냅니다 . 기본 시스템 서비스를 정의하는 경우 프로그램은 데몬 자체를 필요로 하지 않습니다. 이전 스크립트를 사용하는 경우 init.d
프로그램은 여전히 자체 데몬화해야 하지만 프로그램이 수행하는 유일한 작업은 systemd
스크립트 init.d
시작이 완료되었음을 알리는 것뿐입니다. (이렇게 하면 데몬에서 일부 시작 실패를 확인할 수 있지만 불행하게도 많은 기존 프로그램이 데몬 단계 후에 시작 실패를 겪을 수 있습니다.)
스크립트 가 자체적으로 중지하고 다시 시작하는 데 스크립트 systemd
가 반응하는지 여부와 어떻게 반응하는지 걱정하고 싶지 않습니다 .init.d
답변2
귀하의 목표를 올바르게 이해하고 있는지 확실하지 않지만 이것은 나에게 효과적입니다.
실제로 지속적으로 실행되는 프로세스인 "데몬"을 시작합니다.
top -d1 >out
tail -f out
원하시면 두 번째 터미널에서- 세 번째 터미널에서 나는 달린다
kill -STOP $(ps -eFH | grep "top -d" |grep -v grep|awk '{print $2}'
데몬을 시작한 첫 번째 터미널에 "hang" 메시지가 표시되지만 out
파일에는 그러한 메시지가 없습니다.