쉘 스크립트를 데몬으로 실행하는“적절한”방법 프로세스의 포크 모두 닫는다 파일 설명자를

daemontools 또는 daemonize 와 같은 외부 도구를 사용하지 않고 시작할 때 데몬으로 실행하려는 쉘 스크립트 를 작성 중 입니다.


리눅스 데몬 작성 하우투

에 따르면 리눅스 데몬 쓰기 HOWTO 하는 적절한 데몬은 다음과 같은 특징이 있습니다 :

  • 부모 프로세스의 포크
  • 모두 닫는다 파일 설명자를 (즉, stdin, stdout, stderr)
  • 쓰기 위해 로그 를 엽니 다 (구성된 경우)
  • 변경 작업 디렉토리 를 지속되는 디렉토리 로 (보통 /)
  • 파일 모드 마스크를 재설정합니다 (umask)
  • 고유 한 세션 ID를 만듭니다. (SID)를

데몬 라이즈 소개

데몬으로 소개 진술, 더 나아가 그 또한 일반적인 데몬 :

  • 제어 터미널 에서 분리 (있는 경우) 모든 터미널 신호를 무시합니다.
  • 그것에서 분리 프로세스 그룹
  • 핸들 SIGCLD

어떻게이 모든이 작업을 수행 할 것 sh, dash또는bash 단지 일반적인 리눅스 도구와 스크립트?

데비안 이 우리의 주요 관심사 이지만 스크립트는 추가 소프트웨어없이 가능한 많은 배포판에서 실행될 수 있어야합니다 .


참고 : 제가 답변을 많이가 거기에 알고 StackExchange의 사용 추천 네트워크 nohupsetsid,하지만 어느 이러한 방법 태클의 모든 위의 요구 사항을.


편집 : 데몬 (7) 맨 페이지는 이전의 스타일 사이에 약간의 차이가있을 것 같다 있지만 또한, 일부 포인터를 제공 SysV데몬과 새로운 systemd것들. 다양한 배포판과의 호환성이 중요하므로 답변에 차이점이 분명하게 표시되도록하십시오.




답변

systemd 를 사용 하면 간단한 단위를 만들어 스크립트를 데몬으로 실행할 수 있어야합니다. 많은 다른 옵션이 있습니다추가 할 수 이 있지만 이는 가능한 한 간단합니다.

스크립트가 있다고 가정 해보십시오 /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

단위를 만듭니다 /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

[Service]
ExecStart=/usr/bin/mydaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target 

당신이 실행하는 악마를 시작하려면

systemctl start mydaemon.service 

부팅시 시작하려면 활성화하십시오

systemctl enable mydaemon.service

경우 리눅스 배포판의 대부분은 오늘날된다 systemd 기반 시스템에서,이 정말 외부 도구가 아닙니다. 부정적인 점은 모든 곳에서 작동하지 않는다는 것입니다.


답변

아마 여기에 뭔가 빠졌을 것입니다. 왜 정확히 nohup적절 하지 않습니까? 물론 이것 만으로는 충분하지 않지만 보충하는 것은 간단 해 보입니다.

#!/bin/bash

if [ "$1" = "DAEMON" ]; then
    # is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
    trap '' INT
    cd /tmp
    shift
    ### daemonized section ######
    for i in $( seq 1 10 ); do
        date
        sleep 5
    done
    #### end of daemonized section ####
    exit 0
fi

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
umask 022
# You can add nice and ionice before nohup but they might not be installed
nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &

최대한 멀리 볼 수:

  • 출력이 적절하게 리디렉션됩니다 (필요한 경우 / dev / null 사용)
  • umask가 상속됩니다
  • stdin 그러나 부모 스크립트의 끝에서 사망
  • daemon.sh 스크립트는 init(또는 systemd)

나는 명백한 것을 놓치고 있다는 강한 느낌을 가지고 있습니다. 공감,하지만 그것이 무엇인지 말 해주세요 🙂


답변

screen대부분의 배포판에 포함 된 Linux 명령은 쉘 스크립트를 데몬화할 수 있습니다. 자주 사용합니다. 분리 된 화면 세션을 시작, 나열 및 종료하는 간단한 예는 다음과 같습니다.

# screen -dmS Session_Name  bash -c "while true; do date; sleep 60; done"

# screen -ls
There are screens on:
        8534.Session_Name       (04/04/2018 08:46:27 PM)        (Detached)

# screen -S Session_Name -X quit