出力をstdoutまたはファイルにリダイレクトする(両方ではない)

出力をstdoutまたはファイルにリダイレクトする(両方ではない)

対話的に呼び出されたときに標準出力に書き込むが、別のスクリプトで呼び出され、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-znullかどうかテスト)を使用して、変数が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"スクリプトの実行中に標準出力をリダイレクトします。

デモ:

  1. 変数が定義されていません。 stdoutとして出力されます。

    $ bash interactive.sh
    Sat Jan  6 19:06:02 EST 2018
    hello world
    
  2. 変数定義、ファイルへの出力

    $ env EVENT_LOGGER="./event.logger" bash interactive.sh
    $ cat event.logger
    Sat Jan  6 19:06:13 EST 2018
    hello world
    

関連情報