Bashでリダイレクトを停止する方法


8

私が使う :

exec >script.log 2>&1

スクリプトですべての出力をファイルにリダイレクトします。スクリプトの最後に、メッセージを画面に出力したいと思います。リダイレクトを停止するにはどうすればよいですか?

回答:


12

execもう一度呼び出して、元の記述子を復元できます。それらをどこかに保存しておく必要があります。

exec 3>&1 4>&2 1>script.log 2>&1
 logged portion 
exec 1>&3 2>&4
echo >&2 "Done"

ログに記録された部分では、追加の記述子にリダイレクトすることにより、1つのコマンドに元の記述子を使用できます。

echo "30 seconds remaining" >&3

または、スクリプトのログに記録された部分を複合コマンド内に配置して、その複合コマンドをリダイレクトすることもできます。リダイレクトされた部分内のどこかにあるトラップで元の記述子を使用する場合、これは機能しません。

{
 logged portion 
} >script.log 2>&1
echo >&2 "Done"

エコーについての発言>&3は、これを私の好ましい解決策にします。再度、感謝します)!
ウィレム

6

stdoutとstderrに追加のfd 3と4を使用し、スクリプトの最後で単純に1と2をリダイレクトします。

exec 3>&1 4>&2
exec >script.log 2>&1

echo "Some code"

exec >&3 2>&4
echo "Done"

これはエラーを返します:exec 3>/dev/stdout 4>/dev/stderr -bash: /dev/stdout: Permission denied
Willem

このエラーは、別のユーザー内でスクリプトを起動しようとしたときに発生する可能性があります。スクリプトをsudo経由で使用していますか?
ラッシュ

はい、それだけです。別のアカウントに対してsuを実行し、コードを実行しました。私が書いているスクリプトはsudoを介して実行されるため、そこで同じ問題が発生します。代わりはありますか?
ウィレム

いくつかのエレガントな解決策があると思いますが、残念なことに、セキュリティの観点からは絶対に受け入れられない唯一のオプションを知っています。ターゲットユーザーを初期ユーザーのプライマリグループに追加し、/ proc / self / fd / 1にグループ書き込み権限を追加しますスクリプトの起動前。(またはさらに脆弱な場合-すべてのユーザーに一時的な書き込みアクセス許可を作成し、グループを変更せずにスクリプトが完了したらすぐに削除します)。
ラッシュ

1
@Willemこれは、ファイルを再度開く代わりにファイル記述子を使用することで簡単に修正できます。私の編集を参照してください。
Gilles「SO-邪悪なことをやめなさい」2013

1

最初に、ttyがあるかどうかを確認する必要があります。

if tty -s; then
    echo "Hello, World" > $(tty)
fi

1
この方法では、出力を外部プログラムにフィードできないことに注意してください。
2013年

外部ttyユーティリティを使用する必要はありません。特別なデバイスにリダイレクトできます/dev/tty
追って通知があるまで一時停止。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.