バックグラウンドまたはブートスクリプトのログ出力


10

特定のイベントのためにシステムデーモンによって実行される短いスクリプトがあります。イベントが発生し、スクリプトが実行されていることはわかっていますが、意図したとおりに動作しません。不思議なことに、それを手動で実行するとそうなるので、非常に混乱しています。

何が起こっているのか、どうすればわかりますか?スクリプトは基本的に次のような一連のコマンドです。

/bin/foo on 3
sudo bar a

これは、システムスクリプトのデバッグに関するチュートリアルを目的としていることを理解していますが、少々すぎU&Lます。タイトルを誤解しており、「デバッグのためにシステムスクリプトの出力をログに記録する」ことで目的がより明確になるとお勧めします。また、これらのfoo bar例を読んだとき、私の脳は凍りつき、より現実的な世界に見えるものが好きです。投稿を編集するのは気が進まないので、改善できると思われる場合は、このままにしておきます。
ミリウェイズ2016

1
@Milliwaysそうですね、 "システムスクリプト"はとにかく誤称だったので、タイトルを変更しました。私はフーバーのことについては同意しません-人々は、あらゆる文化でそうであるように、一般的な専門用語/口語表現を認識することを学ぶ必要があります。また、2つを組み合わせた後でも、それは良い笑いです。
ゴルディロックス

回答:


8

まず、スクリプトがシステムデーモンによって実行され、そのデーモンがroot権限で実行されている場合、を使用する必要はありませんsudo。これにはinit(およびsystemd)が含まれ、これにはが含まれrc.localます。そのデーモンがされている場合ではない root権限で実行している場合、sudoしない限り動作しません/etc/sudoersように(パスワードなし)を許可するように設定されています。Raspbianユーザーはpi、デフォルトで何でもできるようになっているため、混乱する可能性があります(また、調べてみると、/etc/sudoersそれがどのように行われるかがわかります)。

次に、次のbashようなサブシェルで実行することにより、bashスクリプト内の任意のスクリプトまたはコマンドセットからの出力をキャプチャできます。1

(
    /bin/foo on 3
    sudo bar a
) &> /var/log/myTestLog.txt

()示しサブシェルを。この中にあるものからのすべての出力は、/var/log/myTestLog.txtファイルにリダイレクトされています。いくつかのメモ:

  • &>バシズムです。したがって、スクリプトが最初の行のシバンを介して実行される場合、それは#!/bin/bashだけでなくである必要があります/bin/sh「バシズム」はbashシェルでのみ機能します。

    これには/etc/rc.local、デフォルトで使用されるが含まれます/bin/sh(つまり、はい、これをに安全に変更できます/bin/bash)。

  • /var/log書き込みにはroot権限が必要です。プロセスにそのようなものがない場合は、使用できることがわかっているディレクトリを使用または作成します。確信が持てない場合、システムをシャットダウンまたは再起動せずにこれをテストできる場合/tmpは、誰でも(つまり誰でも)書き込み可能なを使用してください。ただし、/tmpブート間で持続しません。また、RAMベースの小さなパーティションであるため、ギグのデータを書き込まないでください。それはあなたのSDカードではありません[実際にはRaspbianの現在のバージョンではありますが、実際にはこれを当てにしないでください]

  • &>内のすべてが上書きされmyTestLog.txtます。代わりに、既存のログに追加したい場合は、デバッグ目的に適している可能性があります&>>。次に、次のようにそのサブシェルの先頭にコマンドを追加できます。

    echo Starting $(date)

    各実行から情報を分離するため。これが何をするかわからない場合は、コマンドラインで試してください。

この最後の点は、何も出力しないコマンドに関して実行できることの良い例ですが、それらのほとんどは、たとえば-v「verbose」を含めた場合に実行できます。一部のコマンドに-vは「バージョン情報を印刷する」という意味があります。コマンドのmanページを見て、これが機能するかどうか、およびどのように機能するかを確認してください(一部のコマンドは、とは異なるスイッチも使用しています-v)。

慣例により、コマンドは完了すると値0を返します。これは「終了ステータス」と呼ばれることもあり、通常は表示されませんが、シェルではが表示されますecho $?。やってみる

 ls /
 echo $?
 ls /nonexistantdir
 echo $?

0と2が表示されます。その後ls、「終了ステータス」の下のmanページを見ると、かなり具体的ではない、謎めいていることがわかります。

2      if serious trouble (e.g., cannot access command-line argument).

それは何よりも良いかもしれないしそうでないかもしれませんが、あなたはそこに行きます。

少なくとも、何らかの理由でコマンドが失敗したことを示しています。終了ステータスでは、次のようなこともできます。

/bin/foo && sudo bar

&&「最初のコマンドが成功した場合、」この場合の手段では、最初のコマンドを想定すると、(彼らは通常行う理由である)0を返すの規則を使用しています。/bin/fooが機能しない、見つからないなどの場合は、sudo bar発生しません。

ロギングメッセージと条件付き実行(&&)を組み合わせて使用​​すると、問題の把握に近づくか、少なくとも問題の解決に役立つ他の人に役立つ情報を取得できます。 それがなければ、他の誰もができることのほとんどは推測です。


1.次を使用して、スクリプト全体に対して同じ出力リダイレクトを内部から実行できます。

exec &> /var/log/myTestLog.txt

上部(または任意の場所、それ以降のすべてに適用されます)。


2

デーモンとしてスクリプトを実行するとき、人々が忘れがちな1つの重要な側面は、シェル環境、$PATH特に変数です。あなたの例では、2行目$PATHsudois の完全な名前に依存してい/usr/bin/sudoます。ユーザーシェルは、/usr/bin実行可能ファイルを検索するときに検索するように指示されているため、それだけを知っています。同じことがにも当てはまりますbar

sudoスクリプトをデーモンとして実行する場合は必要ないことを考えると、2行目は次のようになります。

/path/to/bar a
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.