printf
スクリプトのbash
の出力をstderr
ではなくstdout
に転送したい。
私はnotが現在ルーティングされている場所からstderr
またはstdout
をリダイレクトすることについて質問しています。出力をデフォルトのprintf
ではなくstderr
からstdout
に送信できるようにしたいだけです。
私は少し実験して、1>&2
to printf
は、以下の例に示すように、私がやりたいように見えます。しかし、私はno bashの使用経験があります。だから私のprimary質問は、「better」方法があるかどうかですこれをbash
で行いますか?
「better」とは、これを行う別の方法があることを意味します。これは、より一般的に使用されている、より慣習的、またはより慣用的な方法ですか?経験豊富なbashプログラマはどのようにそれを行いますか?
#!/bin/bash
printf "{%s} This should go to stderr.\n" "$(date)" 1>&2
printf "[(%s)] This should go to stdout.\n" "$(date)"
また、secondary質問があります。私は知る必要があるので、それほど多くは求めていません。 。
上記はシェルスクリプト内で実行した場合にのみ機能するようです。コマンドラインから試しても動作しないようです。
これが私の意味の例です。
irrational@VBx64:~$ printf "{%s} Sent to stderr.\n" "$(date)" 1>&2 2> errors.txt
{Sat Jun 9 14:08:46 EDT 2012} Sent to stderr.
irrational@VBx64:~$ ls -l errors.txt
-rw-rw-r-- 1 irrational irrational 0 Jun 9 14:39 errors.txt
上記のprintf
コマンドには出力がないはずです。出力はstderr
に送られ、次にファイルに送られるからです。しかし、これは起こりません。え?
まず、はい、1>&2
は正しいことです。
第2に、1>&2 2>errors.txt
の例が機能しない理由は、リダイレクトが正確に行うことの詳細にあります。
1>&2
は、「ファイルハンドル1を、ファイルハンドル2が現在行っている場所を指すようにする」ことを意味します。つまり、stdoutに書き込まれるはずだったものがstderrに送られます。 2>errors.txt
は、「errors.txt
へのファイルハンドルを開いて、ファイルハンドル2がそれを指すようにする」ことを意味します。つまり、stderrに書き込まれるはずだったものがerrors.txt
に入ります。しかし、ファイルハンドル1はまったく影響を受けないため、stdoutに書き込まれたものは引き続きstderrに送られます。
最初に行う操作は「2>errors.txt 1>&2
を開いてstderrがポイントする」ため、stderrとstdoutの両方への書き込みがerrors.txt
に行われるerrors.txt
が適切です。 2番目の操作は、「stdoutが現在stderrが指している場所を指すようにする」です。
それは私には理にかなっているようです。ただし、1
は必要ありません。これはそのまま動作しますが、暗黙のとおりです。
printf "{%s} This should go to stderr.\n" "$(date)" >&2
操作順序の問題があります:
$ printf "{%s} Sent to stderr.\n" "$(date)" 2> errors.txt 1>&2
$ ls -l errors.txt
-rw-r--r-- 1 carl staff 47 Jun 9 11:51 errors.txt
$ cat errors.txt
{Sat Jun 9 11:51:48 PDT 2012} Sent to stderr.
質問はいくつかの混乱を示しているようです。 stdoutをリダイレクトするのではなく、printfに出力をstderrに送信させたいだけですが、そのためにはリダイレクトを使用する必要があります。
Printfコマンドは常に通常の出力をstdoutに送信します。それがprintfが行うことです。あなたが望むものを達成するために、あなたはシェルがstdoutがあなたが出力を行きたいどこにでも一時的に指すように手配する必要があります。一時的に言うことに注意してください。次のようなコマンドを入力すると
$ printf "Hello World!" >&2
シェルは、printfステートメントの実行中にstdoutハンドルを変更します。次に、シェルは次のコマンドを続行する前にstdoutの元の値を復元します。実際、stdoutを永続的にリダイレクトしたい場合は、特別なコマンドを使用します
$ exec >&2
シェルがこれを実行した後、シェルはstdoutハンドルの元の値を記憶しなくなります。
典型的なイディオムは次のとおりです。
echo foo >&2 # you don't need to specify file descriptor 1
echo foo > /dev/stderr # more explicit, but wordier and less portable