シェルスクリプト内のリダイレクト付きのコマンドnohup tailが特定の状況下で正しく呼び出されない


-2

bashスクリプトのtailコマンドが、2つのパラメータのうち1つのパラメータのみを指定してリモートから呼び出されたときに正しく機能しないという問題があります。しかし、以下の場合は正しく機能します。

  • 1パラメータでローカルで直接実行
  • 2パラメータでローカルで直接実行
  • 2パラメータでリモートから実行

followで末尾から始まるスクリプトを以下に書きました。それは2つのパラメータを取ります。

  1. TESTNAME:このパラメータは必須です。これはテストケースの名前です。この名前のログファイルを作成します。
  2. SLAVE_HOST:このパラメータはオプションです。提供されている場合、提供されているスレーブホストにSSHで接続し、同様のスクリプトを起動します。

    #!/bin/bash
    TESTNAME="$1"
    
    testdate=$(date +'%m_%d_%Y')
    REG_DIR=/opt/reg-test-results/REG_"$testdate"
    
    #create regression results directory if it does not exist
    mkdir -p "$REG_DIR"
    
    FILENAME="$REG_DIR"/"$TESTNAME"
    
    #if file already exists, create a new one with current time stamp appended to name
    if [ -f "$FILENAME" ]; then
           TIME=$(date +'%m_%d_%Y-%H.%M.%S')
           FILENAME="$FILENAME"_"$TIME"
    fi
    
    echo "$FILENAME" > /opt/reg-test-results/currentTestName
    
    #start tailing
    nohup tail -f -n0 /path/to/log/files/*/*server.log > "$FILENAME" &
    echo "$!" > $REG_DIR/reg_tail.pid
    
    #if slave host is provided, start tailing logs on slave also
    if [ "$#" -gt 1 ]; then
           SLAVE_HOST="$2"
           ssh "$SLAVE_HOST" /path/to/script/startTailLogTestCaseSlave.sh "$FILENAME"
    fi
    

コードの最初の数行は、パラメーターを変数に保存し、末尾のログが送られるログファイルのディレクトリ構造とファイル名を作成します。 その後、ログの最後尾とログファイルへの転送を開始するnohup tailコマンドがあります。これは正しく機能していないコード行です。それから2番目の引数が与えられた場合、それはそのホストにSSHで接続し、そこでコマンドを実行します。

問題:リモートから実行して両方のパラメータを渡すと、このスクリプトを実行した後に末尾プロセスが実行され、ログファイルにコンテンツが正しく入力されていることがわかります。ただし、最初のパラメーターのみを指定すると、reg_tail.pidファイルに新しいプロセスIDが表示されますが、ログファイル($ FILENAME)は作成されず、末尾のプロセスが実行されていないため、末尾から開始して直ちに停止します。

スクリプトは、マシン上で直接実行されると、1つのパラメータまたは両方で完全に実行されます。

「リモートから実行している場合」とは、マシンにSSHで接続してスクリプトを呼び出すという意味です。例えば:

$ ssh -t user@host /path/to/script/script.sh testcasename.log

デバッグ作業

これは、set -xを使用してリモートマシンから実行したときに表示されるものです。

2番目の引数が渡されてすべてが正常に実行されると、最後にnohup tailが実行されます。

  ....
  + echo 13441
  + '[' 2 -gt 1 ']'
  + SLAVE_HOST=slaveHost
  + ssh slaveHost /path/to/script/startTailLogTestCaseSlave.sh /opt/reg-test-   results/REG_09_11_2015/logs2.log
  + nohup tail -f -n0 /path/to/logs/../check-server.log ...
  nohup: redirecting stderr to stdout
  Connection to hostname closed.

最初の引数だけが渡されると、nohup tailは実行されません。

  ...
  + echo 13607
  + '[' 1 -gt 1 ']'
  Connection to hostname closed.

(1)うわー。 hostAにログインしています。 ssh hostB scriptname filename hostC、そして スクリプトが呼び出す ssh hostC scriptname filename?設計を単純化できるかどうかを確認してください。 (2)スクリプトは tail コマンドの前に ssh "$SLAVE_HOST" … コマンド - しかしあなたの set -x 診断出力ショー tail 後に ssh。それを説明する気がしますか? (3)正当な理由がない限り、シェル変数を引用符で囲む必要があります。 きっと あなたは自分がしていることを知っています。
Scott

なぜあなたは必要ですか nohup そもそもここで?この場合、出力ファイル記述子がめちゃくちゃになる可能性があります。
Breakthrough

みんなありがとう。 @Scott、#1に注目。ありがとう。 #2について、これは私が見ている順番です。理由はわかりません。 2番目の引数を渡すと、末尾には常に末尾が実行されます。 SLAVE_HOSTに値 "null"の文字列を渡すなど、さまざまな方法を試し、値が "null"の場合はsshではないという条件を追加しました。 tailコマンドがsshの前であっても、sshコマンドが実行されたときにのみtailを開始し、sshの後にtailを開始します。 #3について、常に引用符を使用するようにコードを更新しました。
Neha Sharma

@Breakthrough、nohupの削除は役に立ちませんでした。
Neha Sharma

@NehaSharmaなぜ追加したのですか nohup そもそも?説明することはここで手元にある問題をデバッグするのを助けるかもしれません。あなたがせずに同じ振る舞いをするならば、それは言われています nohup まったく、それはそもそもあなたの特定の問題や質問とは何の関係もありません。
Breakthrough

回答:


0

tailコマンドの後に遅延を追加することで問題を解決しました。

nohup tail -f -n0 /path/to/log/files/*/*server.log > "$FILENAME" 2> test.err < /dev/null &
echo "$!" > "$REG_DIR"/reg_tail.pid

#without this delay, the above tail command is not being executed when only one 1 argumet is passed
sleep 1

#if slave host is provided, start tailing logs on slave also
if [ "$#" -gt 1 ]; then

関係ないのに、なぜsshコマンドが実行された後に動作するのでしょうか。だから、私は遅れを追加することにしました。私は専門家ではありませんが、それは競争状態のように見えます。末尾のバックグラウンドプロセスは最後に実行されるようにスケジュールされていましたが、sshコマンドが実行されなかった場合は、末尾プロセスが実行される前にスクリプトが終了してセッションが終了しました。メインプロセスをスリープ状態にすると、プロセス(またはスレッド)を実行するように調整する機会が与えられます。それを考えると、私はこの解決策が最善であるかどうかわからない。私がsleepの代わりにwaitを使うと、 "tail -f"が動き続けるので動けなくなります。私はこのスクリプトを使ってログを確認してからテストケースを実行しています。テストケースの実行が完了した後、私はそれが格納されている場所からtailのpidを読み、tailを殺す別のスクリプトを実行しています。私の理解が間違っているかどうか、またもっと良い解決策があるかどうかを教えてください。

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