このBourneシェルスクリプトで `exec 2>&1`が失敗するのはなぜですか?

このBourneシェルスクリプトで `exec 2>&1`が失敗するのはなぜですか?

以前のkshスクリプトをBourneシェルに移植しています。古いkshスクリプトには次のコードが含まれています。

#!/bin/sh

tmpLog=/var/tmp/logfile.$$

exec 1> $tmpLog
exec 2>&1

eval $*
another_command_1
another_command_2

私が読んだところ、これら2つのexecステートメントは$ *、another_command_1、another_command_2、そして次のコマンドの両方を実行し、そのコマンドのすべてのSTDERRとSTDOUTを/var/tmp/logfile.$$。スクリプトこのスクリプトを使用している場合、スクリプトはにありますexec 2>&1

stefanl@host:~ $ sh -xv ./output.sh echo "Hello"
#!/bin/sh

tmpLog=/var/tmp/logfile.$$
+ tmpLog=/var/tmp/logfile.39918

exec 1> $tmpLog
+ exec
exec 2>&1
+ exec
stefanl@host:~ $

コマンドラインからこのコマンドを実行すると、実行後にシェルがフリーズしますexec 2>&1

stefanl@host:~ $ tmpLog=/var/tmp/logfile.$$
stefanl@host:~ $ exec 1> $tmpLog
stefanl@host:~ $ exec 2>&1
### FREEZE ###

私の質問:

  1. 何をすべきですかexec 2>&1
  2. なぜ私に失敗したのですか?

ベストアンサー1

あなたのスクリプトは失敗しません。正常に動作します。exec >logfile; exec 2>&1標準出力と標準エラーlogfile。現在のシェルでこれらのリダイレクトを直接実行すると、端末からすべての出力が送信されたため、シェルがハングしているように見えます。

xtrace()オプションの出力はset -x常にファイルディスクリプタ2の標準エラーに移動することに注意してください。ログファイルに送信するファイル記述子です。そこで残りの内容を見つける必要がありますexec 2>&1

おすすめ記事