bashスクリプトから出力をログファイルとコンソールにリダイレクトする際に問題が発生しました。

bashスクリプトから出力をログファイルとコンソールにリダイレクトする際に問題が発生しました。

すべての出力をログファイルとstdout(コンソール)の両方に正常にリダイレクトするシェルスクリプトがあります。ところで、シャットダウン時にキーボードから任意のユーザー入力を待っているようです(実験的には任意のキーが機能しているようです)...だからスクリプトを実行して出力を見ると、シャットダウンしてキーを押す必要があるようです。端末プロンプトで、まずスペースバー記号が再び表示されます。その後、入力するとecho $?正しい終了コードが提供されます。

このスクリプトの基本は次のとおりです。

#!/bin/bash
LOG="./test.log"
rm -f $LOG
exec > >(tee $LOG) 2>&1
if [[ "$1" = "T" ]]; then
 echo "twas true..."
 exit 0
else
 echo "twas false..."
 exit 100
fi

助けてくれてありがとう...スペースバーを押したくないだけでなく、何が起こっているのか理解したいですか?

改訂:戦うべきだと思う入力する端末プロンプトを復元します。私の限られた経験に基づいてメモコマンドは私のスクリプトが終了したようです強く打つシェルは中断可能な省電力状態にあります。S。端末プロンプトの出力が消費されたか、誤ってリダイレクトされているようです。なぜかわかりません……

答え1

マイコンピュータで問題を再現できます。$PS1実行中は印刷されますが、tee $LOGスクリプトの終了後に印刷されないことがわかります。スクリプトを実行した後、コマンドプロンプトは空ですが、実際に次のコマンドを入力すると実行されます。

>()プロセスの交換がバックグラウンドで実行されているようです。teeこれにより、すべての出力が対応するexecバックグラウンドプロセスにリダイレクトされます。しかし、tee背景は依然として出力を端末に印刷します。走るとこんな感じです。syslog | tee&

すべてのシェル出力がバックグラウンドプロセスに達すると、teebashはコマンドプロンプトを印刷します$PS1。これは、すでに新しいコマンドを入力できることを意味します。そして、コマンドプロンプトを印刷した後にのみ、コマンドは出力をバックechoグラウンドプロセスに印刷してから端末にtee印刷teeします。

まるでスクリプト全体をバックグラウンドで実行したのと同じです。

これは、スクリプト全体が実行された後にコマンドプロンプトが印刷されない理由を理解しています。良いecho "twas true..." | tee $LOG&。ここで意味するのは、&「バックグラウンドで前のコマンドを実行します」です。

次のコードを試してください。同じことを行いますが、この問題は発生しません。

#!/bin/bash
LOG="./test.log"
rm -f $LOG
{
    if [[ "$1" = "T" ]]; then
     echo "twas true..."
     exit 0
    else
     echo "twas false..."
     exit 100
    fi
} | tee $LOG 2>&1

返品。ファイルはデフォルトで書き換えられているため、必要teeないようですrm -f $LOG

関連情報