start-stop-daemon에 의해 시작된 프로세스의 stdout을 어떻게 기록 할 수 있습니까?


120

다음으로 시작되는 간단한 프로세스를 실행하기 위해 init 스크립트를 사용하고 있습니다.

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS

$ DAEMON이라는 프로세스는 일반적으로 로그 정보를 표준 출력으로 인쇄합니다. 내가 알 수있는 한이 데이터는 어디에도 저장되지 않습니다.

$ DAEMON의 stdout을 파일 어딘가에 쓰거나 추가하고 싶습니다.

내가 아는 유일한 해결책은 start-stop-daemon에게 $ DAEMON 대신 쉘 스크립트를 직접 호출하도록 지시하는 것입니다. 그런 다음 스크립트는 $ DAEMON을 호출하고 로그 파일에 기록합니다. 그러나 데몬 자체를 수정하는 것과 같이 일반적인 작업을 해결하는 잘못된 방법으로 보이는 추가 스크립트가 필요합니다.

답변:


127

ypocat의 답변을 확장하려면 댓글을 달 수 없습니다.

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
 --make-pidfile --pidfile $PIDFILE --background       \
 --startas /bin/bash -- -c "exec $DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"

exec데몬을 실행하는 데 사용 하면 stop이 bash 부모 대신 자식 프로세스를 올바르게 중지 할 수 있습니다.

--startas대신 사용 --exec하면 프로세스가 PID에 의해 올바르게 감지되고 start가 여러 번 호출되는 경우 데몬의 여러 인스턴스를 잘못 시작하지 않습니다. 그렇지 않으면 start-stop-daemon은 / bin / bash 프로세스를 찾고 데몬을 실행하는 실제 자식 프로세스를 무시합니다.


2
이것은 대체하여 다시 데몬을 종료 주로하기 때문에 @ypocat의 것보다 훨씬 더 나은 솔루션 --start으로는 --stop실제로 작동합니다.
aef 2014 년

init.d 대신 rc.local에서이 명령을 실행하려고했습니다 ... 동일한 결과를 얻는 것 같지 않습니다. 그러나 SSH를 통해 쉘에서 실행하면 매력처럼 작동합니다!
nemo

1
첨부 파일은 start-stop-daemon --test (...)어떻게 생겼습니까?
Abdull

2
@MattClimbs 시작할 때마다 파일을 덮어 씁니다. 추가 하는 >>대신 사용하십시오 >.
Meow

2
로그가 비었기 때문에 (나처럼) 놀라기 전에, 이것이 버퍼링된다는 것을 알아 두십시오! "exec stdbuf -oL -eL $ DAEMON $ DAEMONARGS> $ LOGFILE 2> & 1"을 사용하여 출력이 각 줄을 플러시하도록 할 수 있습니다 ( blog.lanyonm.org/articles/2015/01/11/…에서 )
piers7

47

다음을 수행해야합니다.

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec /bin/bash -- -c "$DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"

또한 --chuid또는 을 사용하는 경우 --user사용자가 /var/log또는 기존 /var/log/some.log. 가장 좋은 방법은 해당 사용자가 소유하도록하는 /var/log/subdir/것입니다.


1
환상적입니다, ypocat 감사합니다. 오늘은 로그를 저장하는 것 외에도 --exec가 허용하지 않는 비 바이너리 스크립트를 실행해야했지만 트릭은 작동합니다!
joeytwiddle

8
단점은 ... 서비스를 중지하면 bash가 죽지 만 자식 프로세스 bash가 시작되지는 않습니다! (제 경우에는 DAEMON = 커피).
joeytwiddle

1
나는 do_stop의 맨 위에있는 bash 프로세스의 모든 자식 프로세스를 죽임으로써이 문제를 해결했습니다. bashPID=$(cat $PIDFILE); [ -n "$bashPID" ] && pkill -P "$bashPID"
joeytwiddle 2012

5
알아두면 좋은 점과 pkill해결책도 있습니다. ... -c "exec $DAEMON..."( "exec"추가) 무엇을할지 궁금합니다 . 지금 당장 접시에 담아 두지 마세요.
youurayy 2011

12
@ypocat 방금 -c "exec $ DAEMON ..."과 함께 작동하는지 확인했습니다. 즉, 핵심 해킹이 필요하지 않습니다.
overthink

40

데몬 출력 캡처를 --no-close시작할 때 이제 매개 변수 를 사용할 수 있어야합니다 start-stop-daemon. 이 새로운 기능dpkgDebian의 1.16.5 버전부터 패키지 에서 사용할 수 있습니다 .

새로운 --no-close 옵션을 추가하여 --background에서 fds 닫기를 비활성화합니다.

이를 통해 호출자는 디버깅 목적으로 프로세스 메시지를 보거나 파일 설명자를 로그 파일, syslog 또는 이와 유사한 것으로 리디렉션 할 수 있습니다.


8
그것은 :( 우분투 12.04에서 그것을 사용할 수없는 부끄러운
레온 래들리

나는 --no-close to work ... 출력은 여전히 ​​내가 init.d 스크립트를 실행하고있는 쉘로 가고있다. :(
stantonk

+1 데비안 스퀴즈에서 데몬 화 된 node.js 서비스로 완벽하게 작동합니다.
연설자

2
@stantonk stdout / stderr도 파일에 연결 했습니까? 전체 명령 줄은 다음과 같습니다. 그리고 $ USER 사용자가 로그 파일을 작성할 수 있는지 확인하십시오. start-stop-daemon --start --chuid $ USER --pidfile $ PIDFILE --background --no-close --make-pidfile --exec $ DAEMON -$ DAEMONARGS >> /var/log/xxxxx.log 2> & 1
nharrer

1
이것은 openrc에서는 사용할 수 없습니다 start-stop-daemon. 그러나 openrc 버전에는 각각 stdout 및 stderr을 리디렉션하는 -1-2옵션이 있습니다.
꼬마 친구

14

openrc (예를 들어 gentoo 또는 alpine linux의 기본값) start-stop-daemon에는 -1-2옵션이 있습니다.

-1, --stdout stdout을 파일로 리디렉션

-2, --stderr stderr를 파일로 리디렉션

따라서 다음과 같이 작성할 수 있습니다.

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS -1 $LOGFILE -2 $LOGFILE

9

데몬의 출력을 캡처하여 파일에 저장하는 것은 그리 어렵지 않습니다.

start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas $DAEMON --no-close \
  -- $DAEMON_ARGS >> $LOGFILE 2>&1

그러나이 솔루션은 logrotate.

출력을 syslog에 캡처하는 것이 더 나을 수 있습니다. 에 데비안 이 systemd 서비스의 동작을 일치합니다. 위의 예제를 다시 작성하려는 다음과 같은 간단한 시도는 데몬을 중지 한 후 두 개의 부모없는 ( "좀비") 프로세스 (로거 및 데몬)를 남기기 때문에 잘못 되었습니다. start-stop-daemon자식 만 종료하고 모든 하위 항목은 종료하지 않기 때문입니다 .

## Do not use this!
start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas /bin/sh \
  -- -c """exec $DAEMON $DAEMON_ARGS | /usr/bin/logger --tag $NAME"""

작동하게하려면 SIGTERM에서 수신 할 때 자식을 종료하는 래퍼가 필요합니다 start-stop-daemon. 몇 가지가 있습니다.

듀 엔데 :
start-stop-daemon --start --background \
  --pidfile $PIDFILE \
  --startas /usr/sbin/duende \
  -- --pid $PIDFILE --chroot=/ --uid 65534 --ident $NAME \
  /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec ${DAEMON} $DAEMON_ARGS"""

참고 : uid=65534은 사용자 nobody입니다.

장점 : 작동하며 비교적 쉽습니다.
단점 : 4 개의 프로세스 (감독자 duende, 권한이 삭제 된 포크 (로거), su데몬 자체); 필수 --chroot; 데몬이 즉시 종료되는 경우 (예 : 잘못된 명령)status_of_proc -p $PIDFILE "$DAEMON" "$NAME" 성공적으로 시작된 것으로보고합니다.

데몬 :
start-stop-daemon --start --pidfile $PIDFILE \
  --startas /usr/bin/daemon \
  -- --noconfig --name $NAME --stderr=syslog.info --stdout=syslog.info \
  -- /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec $DAEMON $DAEMON_ARGS"""

장점 : 3 개 과정 (관리자 daemon, su자체 데몬).
단점 : 데몬 의 명령 줄 옵션이 $PIDFILE혼동 되어 관리가 어렵습니다 . 데몬이 즉시 종료되면 (예 : 잘못된 명령) 성공적으로 시작되었다고보고합니다.status_of_proc -p $PIDFILE "$DAEMON" "$NAME"

pipexec ( 우승자 ) :

start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas /usr/bin/pipexec -- -k \
   -- [ D $DAEMON $DAEMON_ARGS ] [ L /usr/bin/logger --tag $NAME ] '{D:2>D:1}' '{D:1>L:0}'

장점 : 3 개 과정 (관리자 pipexec, logger자체 데몬); 데몬이 즉시 종료되면 (예 : 잘못된 명령) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"오류를 올바르게보고합니다.
단점 : 없음.

이것이 가장 잘 작동하는 가장 쉽고 깔끔한 솔루션입니다.


7

일반적으로 start-stop-daemon백그라운드에서 실행할 때 표준 파일 설명자를 닫습니다. 의 man 페이지에서 start-stop-daemon:

-C, --no-close
데몬을 백그라운드로 강제 할 때 파일 설명자를 닫지 마십시오. 디버깅 목적으로 프로세스 출력을 보거나 파일 설명자를 리디렉션하여 프로세스 출력을 기록하는 데 사용됩니다. --background를 사용할 때만 관련이 있습니다.

이것은 나를 위해 일했습니다.

    start-stop-daemon -b -C -o -c \ 
         $DAEMON_USER -S -x $DAEMON > $DAEMON_LOG 2>&1

4

오래된 메일 링리스트 인용 :

https://lists.ubuntu.com/archives/ubuntu-uk/2005-June/000037.html

쉬운 방법은 start-stop-daemon을 사용하려는 경우 유일한 방법은 다음을 포함하는 작은 스크립트를 만드는 것입니다.

#!/bin/sh
exec /home/boinc/boinc/boinc > /home/boinc/log/boinc.log

그런 다음 해당 스크립트를 start-stop-daemon에 대한 인수로 사용합니다.

그러나 진짜 질문은 처음에 start-stop-daemon을 사용해야하는지 여부입니다.


3

"$ DAEMON $ DAEMON_ARGS> /var/log/some.log 2> & 1"이 로그 파일에 대한 파일 설명자를 닫을 지 확실하지 않습니다. 즉, 데몬이 영원히 실행되면 확실하지 않습니다. logrotate 또는 디스크 공간 정리를위한 기타 메커니즘이 작동합니다. >> 대신>이기 때문에 제안 된 명령은 다시 시작할 때 기존 로그도 자릅니다. 데몬이 충돌 한 이유를 확인하고 자동으로 다시 시작되는 경우 그다지 도움이되지 않을 수 있습니다.

다른 옵션은 "$ DAEMON | logger"일 수 있습니다. logger는 syslog (/ var / log / messages)에 기록하는 명령입니다. stderr도 필요하면 "$ DAEMON 1> & 2 | logger"를 사용할 수 있습니다.


맞습니다. 사용하는 >>것이 일반적으로 데몬에 더 적합하지만 이제 logrotate 규칙을 만들어야 함을 의미합니다!
joeytwiddle 2013

디스크 공간의 경우 파일 을 자르는 방법 은 즉시 공간을 다시 확보합니다 (적어도 ext 파일 시스템에서). 그러나 여전히 기록중인 파일 을 단순히 삭제 하는 방법에주의하십시오 . 핸들이 해제 될 때까지 공간이 회수되지 않으며 더 이상 수동으로 잘라낼 파일 노드를 찾을 수 없습니다!
joeytwiddle 2013

내 요점의 @joeytwiddle 부분은 파일 핸들이 닫히지 않으면 logrotate가 로그를 회전하지 못하는 상황이 있다는 것입니다.
nairbv

--no-close ... | logger나를 위해 작동하지 않습니다 (Debian 7.3, start-stop-daemon 1.16.12). / var / log / messages가 채워져 있어도 start-stop-daemon 스크립트는 돌아 오지 않습니다. :-). 나는 그것을 사용하거나 사용하지 않고 그것을 시도했다 1>&2.
hgoebl

hgoebl 따옴표 안에 "cmd | logger"표현식이 있어야하므로 인터프리터는 start-stop-daemon 표현식이 아니라 로거에 파이핑하는 "cmd"임을 알 수 있습니다.
Wexxor

2

bash라고 가정하면 (일부 다른 쉘에서도이를 허용 할 수 있지만) 다음 행은 다음과 같습니다.

exec >>/tmp/myDaemon.log

향후 모든 표준 출력을 해당 파일로 보냅니다. exec프로그램 이름이 없으면 리디렉션 마법이 수행 되기 때문 입니다. 로부터 bash매뉴얼 페이지

명령을 지정하지 않으면 모든 리디렉션이 현재 셸에서 적용됩니다.

해당 파일의 관리는 물론 또 다른 문제입니다.


이 선이 어디에 배치되어야하는지 명확히 할 수 있습니까? start-stop-daemon초기 질문에서 언급 한 줄 바로 뒤에 ?
Abdull

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.