追加読書

追加読書

私は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

そこには多くの問題があります。

  • ExecStartExecStopシェルのコマンドラインを考えないでください。そうではありません。 systemd マニュアルはこれについて警告します。コマンド置換などのシェル拡張は次のとおりです。いいえこれらのサービス単位ファイル設定で使用できます。これはいいえシェル言語。
  • 開始する実際のサービスマネージャがある場合は、PIDファイルメカニズムを作成しないでください。 PIDファイルは1980年代以降に破損したメカニズムなので、適切なサービス管理によってPIDファイルの必要性が完全になくなりました。サービス管理者がいます。 それいつでも最大1つのサービスインスタンスが実行されることを保証します。 それプロセスIDが追跡されます。 それサービスが終了すると、サービスプロセスに終了信号を送信するタスクが処理される。
  • FIFO の生成やサーバー側のオープンなど、基本的なサーバー側の項目をサーバープロセスに入れないでください。

この方法:

  • サービスユニットとともにソケットユニットを作成します。
  • からFIFOのすべての明示的な処理を削除しますcrashCollector
  • ListenFIFOソケットユニットに使用されます。もちろん絶対パス名が必要です。
  • StandardInput=socketサービスユニットに使用されます。
  • crashcollector標準入力からのみスクリプトを読むようにしてください。
  • crashCollector.
  • すべての信号のキャプチャとcleanup()アイテムをcrashCollector
  • 使用された明示的な殺人とサービスユニットの外部ExecStopで実行したいフォローアップの両方を取ってください。KillMode
  • StandardError=journalサービスユニットに使用されます。
  • log単純エラーからecho 1>&2標準エラーに置き換えられました。

追加読書

おすすめ記事