Stderrをファイルにリダイレクトする方法

バックグラウンドで実行するコマンドを置くためにnohupを使用している間、コンテンツの一部が端末に表示されます。

cp: error reading ‘/mnt/tt/file.txt’: Input/output errorcp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

そのコンテンツをファイルに保存したい。

Linux(および他のOs)には、標準出力(stdout)と標準エラー(stderr)の2つの主な出力ストリームがあります。 エラーメッセージは、表示したものと同様に、標準エラーに出力されます。 古典的なリダイレクト演算子(command > file)標準出力のみをリダイレクトするので、標準エラーは端末に表示されます。 Stderrもリダイレクトするには、いくつかの選択肢があります:

  1. Stdoutを1つのファイルにリダイレクトし、stderrを別のファイルにリダイレクトします:

    command > out 2>error
  2. Stdoutをファイルにリダイレクトする(>out)、そしてstderrをstdoutにリダイレクトします(2>&1):

    command >out 2>&1
  3. 両方をファイルにリダイレクトします(これはすべてのシェルでサポートされていません, bashzsh 例えば、それをサポートしていますが、 shksh しないでください):

    command &> out

さまざまな制御演算子とリダイレクト演算子の詳細については、次を参照してください ここでは、.

最初に注意すべきことは、あなたの目的とシェルに応じていくつかの方法があるということです、したがって、これは複数の側面をわずかに理解す さらに、次のような特定のコマンド timestrace 出力をデフォルトでstderrに書き込み、そのコマンドに固有のリダイレクト方法を提供する場合と提供しない場合があります

リダイレクトの背後にある基本的な理論は、シェルによって生成されたプロセス(シェル組み込みではなく外部コマンドであると仮定)が fork()execve() syscalls、およびその前に別のsyscallが発生します dup2() 前に必要なリダイレクトを実行します execve() 発生します。 その意味で、リダイレクトは親シェルから継承されます。 その m&>nm>n.txt 実行方法についてシェルに通知します open()dup2() syscall(も参照 入力リダイレクトの仕組み, リダイレクトとパイプの違いは何ですか、および 出力リダイレクトで&正確には何を意味しますか )

シェルのリダイレクト

最も典型的なのは、 2>ボーンのようなシェル、など dash (シンボリックリンクされています /bin/sh)と bash;最初はデフォルトでPOSIX準拠のシェルであり、もう1つはほとんどのユーザーが対話型セッションに使用するものです。 それらは構文と機能が異なりますが、幸いにもエラーストリームのリダイレクトは同じように動作します( &> 非標準的なもの)。 Cshとその派生物の場合、stderrリダイレクト そこではうまくいきません。

のはに戻って来てみましょう 2> パート。 注目すべき2つの重要なこと: > リダイレクト演算子を意味します。ここではファイルを開き、 2 実際、これはまさにシェル言語のPOSIX標準がリダイレクトを定義する方法です 第2.7節:

[n]redir-op word

簡単のため > リダイレクションは、 1 整数はのために暗示されます stdout、すなわち、 echo Hello World > /dev/null と同じです echo Hello World 1>/dev/null. そうでない場合、shellはそれらをそのように認識せず、代わりにテキストのリテラル文字列として扱います。 間隔に関しては、integerがリダイレクト演算子のすぐ隣にあることが重要ですが、fileはリダイレクト演算子の隣にあるかどうかのいずれかになります。 command 2>/dev/nullcommand 2> /dev/null うまく動作します。

シェルの典型的なコマンドのやや単純化された構文は次のようになります

 command [arg1] [arg2]  2> /dev/null

ここでのトリックは、リダイレクトがどこにでも表示されることです。 それは両方です 2> command [arg1]command 2> [arg1] 有効です。 のために注意してください。 bash シェル、そこに存在する &> stdoutストリームとstderrストリームの両方を同時にリダイレクトする方法ですが、bash固有のものであり、スクリプトの移植性を追求している場合は動作しない も参照してください Ubuntu Wiki>>&Amp;と2&1の違いは何ですか.

メモ: その > リダイレクト演算子 トランケート ファイルが存在する場合は、ファイルを上書きします。 その 2>> 追加するために使用される可能性があります stderr ファイルに。

あなたが気づくかもしれない場合, > 一つのコマンドのためのものです。 スクリプトの場合、次のようにスクリプト全体のstderrストリームを外部からリダイレクトできます myscript.sh 2> /dev/null または我々は利用することができます execビルトイン. Exec組み込みには、対話的にもスクリプトを介しても、シェルセッション全体のストリームを再配線する力があります。 何かのようなもの

#!/bin/shexec 2> ./my_log_file.txtstat /etc/non_existing_file

この例では、ログファイルは次のように表示されます stat: cannot stat '/etc/non_existing_file': No such file or directory.

さらに別の方法は、関数を介してです。 として シンデレラ 彼の答えで指摘されているように、すでにリダイレクトが添付されている関数宣言を書くことができます。

some_function(){    command1    command2} 2> my_log_file.txt

Stderrに排他的に書き込むコマンド

次のようなコマンド timestrace デフォルトでは、出力をstderrに書き込みます。 の場合には time コマンド、唯一の実行可能な選択肢は、コマンド全体の出力をリダイレクトすることです。

time echo foo 2>&1 > file.txt

または、出力を分離したい場合は、同期リストまたはサブシェルをリダイレクトすることもできます(以下に示すように 関連記事 ):

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

次のような他のコマンド strace または dialog stderrをリダイレクトする手段を提供します。 strace 持っています -o <filename.txt> 出力を書き込むファイル名を指定できるオプション。 また、各サブプロセスのtextfileを書き込むためのオプションもあります。 strace 見ている。 その dialog コマンドは、テキストユーザーインターフェイスをstdoutに書き込みますが、stderrに出力するので、次のようにします 出力を変数に保存します (なぜなら var=$(...) そして、パイプラインはstderrのみを受け取ります)ファイル記述子を交換する必要があります

result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);

しかし、さらに、そこにあります --output-fd 私達がまた利用してもいい旗。 名前付きパイプの方法もあります。 私はについてのリンクされた記事を読むことをお勧めします dialog 何が起こっているのかを徹底的に説明するためのコマンド。

@terdonこれはより具体的な質問であり、より具体的な質問のためにgoogle検索に正しく表示されます。

@nrooseはい、それは表示され続けますが、それは変わりません。 しかし、新しい答えはより一般的な質問に行くべきです。