"exec &>filename"を実行した後、出力を端末に復元します。

"exec &>filename"を実行した後、出力を端末に復元します。

私は次のことをしようとしています:

exec &>filename

その後、私が入力したものを含む何も表示されません。

exec 1>&1狂ったように努力したが、exec 2>&2何も起こらなかった。

シェルを終了せずに出力をstdoutにリダイレクトし、エラーをstderrに別々にリダイレクトするにはどうすればよいですか?ファイル記述子が標準の[in | out]putとstderrを参照する唯一の方法ですか?

答え1

を実行した後、exec &>filenameシェルの標準出力と標準エラーはに移動しますfilename。定義によると、標準入力はファイル記述子0、標準出力はfd 1、標準エラーはfd 2です。

ファイル記述子はリダイレクトまたはリダイレクトされません。常にどこかに移動します(プロセスでこの記述子が開いていると仮定)。ファイル記述子をリダイレクトすることは、ファイル記述子が行く場所を変更することを意味します。を実行すると、exec &>filenamestdoutとstderrは以前に端末に接続され、現在に接続されますfilename

常に現在の端末を参照する方法があります。/dev/tty。プロセスがこのファイルを開くと、常にプロセスのファイルが制御端子、どちらにしても構いません。したがって、そのシェルの元のstdoutとstderrを元に戻したい場合は、リンクされたファイルがまだ存在するため、これを行うことができます。

exec &>/dev/tty

答え2

欲しい

exec &>$(tty)

あなたの質問でやっていることは、ファイルにリダイレクトされた元のstdoutとstderrをstdoutとstderrにコピーすることです。

Gilesの回答で説明されているように、tty現在の端末の端末装置が返されます。これは、ログインシェルから開始/終了までの3つの標準ファイル記述子のデフォルトの場所です。したがって、上記のステートメントは、tty以前と同様に、stdoutとstderrをターミナルデバイスにリダイレクトするという利点を利用します。

移植性が心配な場合(Gilesの回答に対するあなたの意見に基づいて)、2つのアプローチ(ターミナルユーティリティそして/dev/tty文書) は POSIX 標準の一部です。

Gillesのコメントをそのままコピーするには:

There's an advantage to /dev/tty: it works even after exec <somefile, 
whereas $(tty) would complain “not a tty”

関連情報