추가 읽기

추가 읽기

나는 FIFO의 명령을 수신하고 라즈베리 파이에서 디버깅을 위해 몇 가지 파일을 수집하는 스크립트를 작성했습니다.잘 작동내가 시스템 단위 파일을 작성하기로 결정하기 전까지는 말이죠. 실행하면 systemctl start crashcollector스크립트가 시작되지만 실행 중인 파이프에서 아무 것도 읽지 않지만 아무것도 하지 않고 systemctl stop crashcollector서비스를 중지하는 데 시간이 오래 걸립니다. 따라서 많은 작업 일반 파일을 작성했음에도 불구하고 내 유닛 파일에 문제가 있는 것으로 추측됩니다.

배시 스크립트:

#!/bin/bash

collectCrashReport() {
    # teleport to cache dir
    cd /mnt/cache
    # remove any previous report
    rm -rf crash/crashreport_*
    # create report directory
    directory=crashreport_`cat /etc/hostname`_$(date +%Y%m%d%H%M%S)
    mkdir $directory
    cd $directory
    # snatch all the logs
    cp -r /var/log/ .
    ps --no-headers -ax > processes.dump
    # dump dmesg to file 
    dmesg > dmesg.dump
    # create crash dir
    mkdir crash
    # zip the whole thing
    zip -qr /mnt/cache/crash/"$directory.zip" .
    # remove collection dir
    rm -rf /mnt/cache/crashreport_*
    # done and done
}

# check if already running and kill
PIDFILE=/var/run/crashcollector.pid
# check if already running
if [ -f $PIDFILE ]; then
    kill `cat $PIDFILE`
fi
echo $$ > $PIDFILE

cleanup() {
    rm -f $PIDFILE
    exit 0
}
# trap them signals 
trap "cleanup" INT TERM EXIT

that_awesome_pipe="CCPipe"
[ -p $that_awesome_pipe ] || mkfifo $that_awesome_pipe
chmod 766 $that_awesome_pipe
while :; do
    if read line; then
        case $line in
        "collect")
            collectCrashReport
            ;;
        *)
            log "Received bad command $line, ignoring..."
            ;;
        esac    
    fi
done <"$that_awesome_pipe"

시스템 단위 파일:

[Unit]
Description=Crash report collector
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/crashCollector
ExecStop=/usr/bin/kill -9 `cat /var/run/crashcollector.pid`
KillMode=process
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

여기서 정확히 무엇을 놓치고 있는지 잘 모르겠습니다. 해당 if read line블록을 제거하면 모든 것이 작동했습니다.

답변1

거기에는 많은 문제가 있습니다.

  • ExecStart및를 ExecStop쉘 명령줄로 생각하지 마십시오 . 그렇지 않습니다. systemd 매뉴얼은 이에 대해 경고합니다. 명령 대체와 같은 쉘 확장은 다음과 같습니다.아니요이러한 서비스 단위 파일 설정에서 사용할 수 있습니다. 이것은아니요쉘 언어.
  • 시작하는 실제 서비스 관리자가 있는 경우 PID 파일 메커니즘을 생성하지 마십시오. PID 파일은 1980년대 이후 손상된 메커니즘이므로 적절한 서비스 관리를 통해 PID 파일의 필요성이 완전히 사라졌습니다. 서비스 관리자가 있습니다. 그것언제든지 최대 하나의 서비스 인스턴스가 실행되도록 보장합니다. 그것프로세스 ID가 추적됩니다. 그것서비스가 종료되면 서비스 프로세스에 종료 신호를 보내는 작업이 처리됩니다.
  • FIFO 생성 및 서버 측 열기와 같은 기본적인 서버 측 항목을 서버 프로세스에 넣지 마십시오.

이 방법:

  • 서비스 유닛과 함께 소켓 유닛을 생성합니다.
  • 에서 FIFO의 모든 명시적 처리를 제거합니다 crashCollector.
  • ListenFIFO소켓 장치 에 사용됩니다 . 물론 절대 경로 이름이 필요합니다.
  • StandardInput=socket서비스 단위에 사용됩니다.
  • crashcollector표준 입력에서만 스크립트를 읽도록 하세요 .
  • .crashCollector
  • 모든 신호 캡처 및 cleanup()항목을 crashCollector.
  • 사용된 명시적인 살인 과 서비스 유닛 외부 ExecStop에서 수행하려는 후속 조치를 모두 취하십시오.KillMode
  • StandardError=journal서비스 단위에 사용됩니다.
  • log단순 오류에서 echo 1>&2표준 오류로 대체되었습니다 .

추가 읽기

답변2

fifo를 옮긴 후 모든 것이 수정되었습니다 /tmp. 무엇이 변경되었는지는 확실하지 않지만 지금은 모든 것이 원활하게 실행되고 있습니다.

관련 정보