exec >/dev/null 以降標準出力に印刷する方法

exec >/dev/null 以降標準出力に印刷する方法

スクリプトには、標準出力に印刷する長いコマンドのリストがあります。すべての出力を隠したいです。したがって、すべてのコマンドをリダイレクトする代わりに

exec >/dev/null

最初は。

echo通常のリダイレクトを「一時的に無視」して実際にstdoutとして印刷する間に一度呼び出すには、どのようなオプションが必要ですか?

答え1

何でもecho標準出力として印刷されます。/dev/null要点は、元の標準出力がまったく特別ではないか、リダイレクトされた標準出力よりも「本当」であることです。

stdout が元々指している場所のコピーを保持するには、ファイル記述子を別の番号にコピーし、そこに保持したい出力を送信できます。

exec 3>&1            # duplicate original stdout to fd 3
exec 1>/dev/null     # send stdout to /dev/null
printf "what\n"      # this goes to stdout = /dev/null
printf "hello " >&3  # this goes to fd 3 = original stdout
# optionally:
exec 1>&3            # put the original stdout back
exec 3>&-            # close fd 3
printf "there\n"     # to current stdout = original stdout again

または、Bash/ksh93/zshで動的に割り当てられたfdを使用してください(私はこれを正しく実行してください)。

exec {orig}>&1            # duplicate original stdout to some fd,
                          # store number in $orig
exec 1>/dev/null          # send stdout to /dev/null
printf "what\n"           # this goes to stdout = /dev/null
printf "hello " >&"$orig" # this goes to fd in $orig = original stdout
# optionally:
exec 1>&"$orig"           # put the original stdout back
exec {orig}>&-            # close fd in $orig
printf "there\n"          # to current stdout = original stdout again

どちらの場合も、ksh93fd(3以上)にはclose-on-execフラグが表示されますが、$origbash / zshはそうではありません。ただし、bash 5.2以降では、shopt -s varredir_closefds Createdを使用する構文にclose-on-execフラグを追加できますexec {var}>...

このフラグが設定されていない場合、fd 3方法を提供他のコマンドで。たとえば、生の標準出力がパイプに送信され、パイプが開いたままになる可能性があるバックグラウンドプロセスを開始するコマンドを実行すると、実際には問題になる可能性があります。このような人のために走ると、cmd 3>&-この問題は解決されます。

答え2

echo具体的に出力を次に移動する場合スクリプトが起動した端末に移動、あなたが利用できる:

echo "some message" > /dev/tty

/dev/ttyいくつかの「魔法」:どのプロセスを使用しても、そのプロセスに関連する端末に常に接続されます。

もちろん、このようにスクリプトを実行するとどの端末にも接続されていません(たとえば、crontabでまたはoptionsをssh somehost script.sh指定せずに)エラーが発生します。-tssh

$ ssh hostname "echo foo > /dev/tty"
Enter passphrase for key...:
bash: line 1: /dev/tty: No such device or address

$ ssh -t hostname "echo foo > /dev/tty"
Enter passphrase for key...:
foo
Connection to hostname closed.

答え3

echo途中に1つの単純なコマンドのリストがある場合は、次のことができます。

{
  注文する1
  注文する2
  注文するサム
  注文する4
} > /dev/null
echo 'High Five' # スクリプトの標準出力に移動します。
{
  注文する6
  注文する7
  注文する8
  注文する9   
}> / dev / null
echoif- またはループなどの複合コマンド内では、thenこの方法は機能しません。

関連情報