対話的に呼び出されたときに標準出力に書き込むが、別のスクリプトで呼び出され、EVENT_LOGGER変数が呼び出しスクリプトによって定義されている場合は、EVENT_LOGGERファイルに書き込むスクリプトを作成したいと思います。
おそらくこれを行う簡単な方法があります。しかし、私はそれを知りません。もちろん、出力が生成されるすべての場所にこのロジックを追加できます。
if [[ -f $EVENT_LOGGER ]]
then
echo "Some message" >> $EVENT_LOGGER
else
echo "Some message"
fi
ただし、これによりスクリプトに大量が追加されます。
次のようにできたらと思います。
if [[ ! -f $EVENT_LOGGER ]]
then
EVENT_LOGGER = "&1"
fi
その後、すべての出力コマンドは次のようになります。
echo "Some message" >> $EVENT_LOGGER
EVENT_LOGGER が指すファイルまたは標準出力に移動します。
それは動作しません。 $ EVENT_LOGGERをstdoutに解析する別の方法はありますか?
AIX 7.1でksh93を使用しています。
答え1
多くのUnixバリアントでは、filenameを介して標準出力にアクセスできます/dev/stdout
。
if [[ -z $EVENT_LOGGER ]]; then
EVENT_LOGGER=/dev/stdout
fi
…
echo >>"$EVENT_LOGGER" 'This is a log message'
しかし、AIXでも機能するかどうかはわかりません。バラより">/dev/stdout"移植性そしてUnixシステムには/dev/stdin、/dev/stdout、/dev/stderrがありませんか?
または、すべてのロギングを標準出力にし、オプションで標準出力をファイルにリダイレクトします。exec
コマンド名はありませんが、リダイレクトを使用して組み込み関数を呼び出すと、残りのスクリプトに対してリダイレクトが設定されます。
if [[ -n $EVENT_LOGGER ]]; then
exec >>"$EVENT_LOGGER"
fi
…
echo 'This is a log message'
スクリプトによって呼び出されたプログラムの出力は、同じログファイルに移動されます。これを望まない場合は、別のファイル記述子にログオンしてください。
if [[ -n $EVENT_LOGGER ]]; then
exec 3>>"$EVENT_LOGGER"
else
exec 3>&1
fi
…
echo >&3 'This is a log message'
別のアプローチは、必要に応じて機能を異なる方法で定義することです。
if [[ -n $EVENT_LOGGER ]]; then
log () {
echo "$*" >>"$EVENT_LOGGER"
}
else
log () {
echo "$*"
}
fi
…
log 'This is a log message'
何をしても関数を使用することをお勧めします。これにより、ロギングの仕組みを変更したい場合(たとえば、端末やファイルにログ、色を追加、条件付きにするなど)がはるかに簡単になります。
いくつかの一般的な注意:
- このテストは
-f
ファイルが存在するかどうかをテストします。これは良いテストではありません。代わりに-n
(-z
nullかどうかテスト)を使用して、変数がnullでないかどうかをテストします。 =
変数の割り当てでは、シンボルの周りにスペースを入れることはできません。
答え2
あなたはこれが欲しい:
$ cat interactive.sh
#!/bin/bash
if [[ -n "$EVENT_LOGGER" ]]; then
exec 1>>"$EVENT_LOGGER"
fi
date
echo "hello world"
魔法:exec 1>>"$EVENT_LOGGER"
スクリプトの実行中に標準出力をリダイレクトします。
デモ:
変数が定義されていません。 stdoutとして出力されます。
$ bash interactive.sh Sat Jan 6 19:06:02 EST 2018 hello world
変数定義、ファイルへの出力
$ env EVENT_LOGGER="./event.logger" bash interactive.sh $ cat event.logger Sat Jan 6 19:06:13 EST 2018 hello world