ロギングコンテキストが実行されているスクリプトを認識していますか?

ロギングコンテキストが実行されているスクリプトを認識していますか?

私のプログラムをファイルにリダイレクトするとしましょうSTDOUTSTDERR

./script.sh 1> output.log 2> error.log

実行中のプログラムはこれを見つけることができますか?つまり、これらのファイルのパスがわかりますか?

答え1

{ readlink /dev/fd/[1,2] ; echo "out" ; } >./file 2>./error    
{ readlink /dev/fd/0 ; cat ; } <./file

出力:

/home/mikeserv/file
/home/mikeserv/file
/home/mikeserv/error
out

{ readlink /proc/$$/fd/[1,2] ; echo out ; } >./file 2>./error
{ readlink /proc/$$/fd/0 ; cat ; } <./file

出力:

/home/mikeserv/file
/home/mikeserv/file
/home/mikeserv/error    
out

答え2

電話してもいいlsofシェルプロセスで開かれたファイルを一覧表示します。-a -p $$出力をシェルプロセス($$)に制限し、-d 1出力をファイル記述子1(たとえば)に制限し、-F n出力を解析可能な形式で印刷するために使用されます。以下は、ファイル名の任意の文字を処理するシェルの断片です。

output_file=$(lsof -a -p $$ -d 1 -F pn; echo .)
output_file=${output_file%.}
output_file=${output_file#n}

ファイル名に改行文字が含まれていない場合output_file=$(lsof -a -p $$ -d 1 -F pn | sed -n '2s/.//p')

ファイル名が常に存在するわけではなく、特にファイルが削除された場合にはさらにそうです。

Linuxでファイル名にアクセスするもう1つの方法は次のとおりです/proc/$$/fd/proc/$$/fd/1ファイル記述子1のシェルで開いたファイルへの少し魔法のシンボリックリンク(readlinkこのリンクは、返されたファイル名が存在しない場合でも機能します(削除されたファイルなど)。 。

このようにして得られた情報を活用することは一般的に非常に悪い考えです。誰かがスクリプトを呼び出して出力をファイルにリダイレクトする場合は、ファイルの場所によって異なる動作やファイルに追加する以外の方法でファイルに影響を与えた場合、それらはそれを気に入らないでしょう。 1つの例外があります。端末に書き込むか、端末に色や進行状況インジケータを表示するなど、他のもの(パイプ、ソケット、ファイル)に書き込むかどうかによって、異なる反応が必要になる場合があります。ファイル記述子が端末に接続されていることを確認する特定のテストがあります。

if [ -t 2 ]; then
  # stderr is a terminal
  printf 1>&2 '\e[31mError: widget not found\e[0m'
else
  # stderr is not a terminal
  echo 1>&2 'Error: widget not found'
fi

答え3

あなたの場合は、STDOUTファイルに保存しoutput.logSTDERRファイルに保存してくださいerror.log。どちらのファイルも同じディレクトリに保存されますscript.sh

プログラムがこれらのファイルへの「パスを知る」ようにするには、絶対パスを使用する必要があります。

./script.sh > /path/to/output.log 2> /path/to/error.log

答え4

output.logファイルはerror.log現在のディレクトリ(つまり変数値)に作成されます$PWD。プログラムが後でこれらのファイルを使用できるようにするには、スクリプトを実行する前にそのディレクトリを変数に保存します。例は次のとおりです。

OUTDIR=$PWD
./script.sh 1> output.log 2> error.log
# Whatever you want to do else ...
echo The output file : =======
cat $OUTDIR/output.log
echo =========================
echo 
echo The errors file : =======
cat $OUTDIR/error.log
echo =========================

関連情報