
STDERRとSTDOUTを両方の画面に送信し、それをファイル(test.log)に書き込む次の簡単なシェルスクリプトがあります。また、終了時に適切な終了コードを使用して終了しようとします。
このコードでは、最初のメッセージ(ブロック内)をエコーして終了します。ただし、両方の文をエコーし、常にゼロで終了します。
$ cat test.sh
#!/bin/ksh
n_exitstatus=0
{
n_exitstatus=1
echo "Inside block : $n_exitstatus"
exit $n_exitstatus
} 2>&1 | tee -a test.log
echo "Before last exit : $n_exitstatus"
exit $n_exitstatus
$ sh test.sh
Inside block : 1
Before last exit : 0
$ echo $?
0
最初の文をエコーした直後に終了するように(画面とファイルに書き込まれるように)、このスクリプトをどのように変更しますか?
答え1
パイプラインで内部コードブロックを使用できます。これにより、シェルはサブシェルを実行します。 Exitは機能のみを残します。パイプを取り外すと、期待| tee -a test.log
どおりに機能します。
したがって、最も簡単な解決策は、ブロックからパイプを削除し、内部echoコマンドの後に配置することです。
ブロックを本体として関数を生成し、それを実行してから戻り値を使用して、外部コードをさらに実行する前に終了するかどうかを決定することもできます。
編集する 以下は便利なリンクです:http://www.bolthole.com/solaris/ksh-functions.html
答え2
これは次の質問と密接に関連しています。呼び出し方法に関係なく、実行全体を中断するbash関数を書く方法はありますか?
与えられたソリューションの実装受け入れられた回答、我々はこれを持っています:
$ cat test.ksh
#!/bin/ksh
trap 'exit $n_exitstatus' TERM
SCRIPT_PID="$$"
n_exitstatus=0
{
n_exitstatus=1
echo "Inside block: $n_exitstatus"
kill -s TERM $SCRIPT_PID
} 2>&1 | tee -a test.log
echo "Before last exit: $n_exitstatus"
exit $n_exitstatus
$ chmod +x test.ksh
$ ./test.ksh
Inside block: 1
$ cat test.log
Inside block: 1
唯一正しいことは、スクリプトの終了状態が1ではなく0であることです。これは、ゼロのある外部範囲でシャットダウンが発生するためです$n_exitstatus
。