私は次を実行しようとしています:
exec &>filename
この後、入力した内容を含め、何も表示されません。
私は必死に、 exec 1>&1そしてexec 2>&2、何も起こりません。
さて、シェルを殺さずに、出力をstdoutにリダイレクトし、エラーをstderrにリダイレクトするにはどうすればよいですか?ファイル記述子は、標準の[in | out] putおよびstderrを参照する唯一の方法ですか?
私は次を実行しようとしています:
exec &>filename
この後、入力した内容を含め、何も表示されません。
私は必死に、 exec 1>&1そしてexec 2>&2、何も起こりません。
さて、シェルを殺さずに、出力をstdoutにリダイレクトし、エラーをstderrにリダイレクトするにはどうすればよいですか?ファイル記述子は、標準の[in | out] putおよびstderrを参照する唯一の方法ですか?
回答:
実行後exec &>filename、シェルの標準出力と標準エラーはに移動しfilenameます。定義により、標準入力はファイル記述子0、標準出力はfd 1、標準エラーはfd 2です。
ファイル記述子はリダイレクトもリダイレクトもされません。常にどこかに行きます(プロセスがこの記述子を開いていると仮定します)。ファイル記述子をリダイレクトするとは、その場所を変更することを意味します。実行するとexec &>filename、以前はstdoutとstderrが端末に接続されていfilenameましたが、に接続されました。
現在の端末を参照する方法は常にあります:/dev/tty。プロセスがこのファイルを開くとき、それは常にプロセスの制御端末を意味します。したがって、そのシェルの元のstdoutとstderrを取得したい場合は、それらが接続されていたファイルがまだ残っているため、それを行うことができます。
exec &>/dev/tty
/dev/tty場合に$(tty)機能します:/dev/ttyプロセスに制御端末がある限り機能します(プロセスと端末を接続している$(tty)必要があるため、これは期待できる最善です)が、端末はまだ開いている必要があります標準入力で。
あなたが欲しい
exec &>$(tty)
あなたの質問であなたがしているのは、すでにファイルにリダイレクトされている元のstdoutとstderrをstdoutとstderrで複製することです。
Gillesの答えが説明ttyするように、現在の端末の端末デバイスを返します。これは、ログインシェルでデフォルトで3つの標準ファイル記述子が出入りする場所です。したがって、上記のステートメントはtty、以前のようにstdoutとstderrを端末デバイスにリダイレクトするために利用します。
移植性が心配な場合(Gillesの回答に関するコメントによる)、両方の方法(ttyユーティリティと/dev/ttyファイル)はPOSIX標準にあります。
ジルのコメントから逐語的にコピー:
There's an advantage to /dev/tty: it works even after exec <somefile,
whereas $(tty) would complain “not a tty”
/dev/tty後exec <somefileでさえ機能し$(tty)ます。
execコンストラクトは、通常、出力をファイルなどにリダイレクトするために、サブシェルで実行されるスクリプトで使用されます。インタラクティブセッションで使用する方法がわかりません。