Nohupを使用して、バックグラウンドで実行するコマンドを配置すると、コンテンツの一部がターミナルに表示されます。
cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error
そのコンテンツをファイルに保存したい。
Linux(および他のOS)には、標準出力(stdout)と標準エラー(stderr)の2つのメイン出力ストリームがあります。表示するようなエラーメッセージは、標準エラーに出力されます。従来のリダイレクト演算子(command > file
)は標準出力のみをリダイレクトするため、端末には標準エラーが引き続き表示されます。 stderrもリダイレクトするには、いくつかの選択肢があります。
Stdoutを1つのファイルにリダイレクトし、stderrを別のファイルにリダイレクトします。
command > out 2>error
Stderrをstdout(&1
)にリダイレクトしてから、stdoutをファイルにリダイレクトします。
command >out 2>&1
両方をファイルにリダイレクトします(これはすべてのシェルでサポートされているわけではありません。たとえば、bash
およびzsh
はサポートしていますが、sh
およびksh
はサポートしていません)
command &> out
さまざまな制御およびリダイレクト演算子の詳細については、 here を参照してください。
最初に注意することは、目的とシェルに応じていくつかの方法があるため、複数の側面を少し理解する必要があることです。さらに、time
やstrace
などの特定のコマンドは、デフォルトでstderrに出力を書き込み、そのコマンドに固有のリダイレクト方法を提供する場合と提供しない場合があります。
リダイレクトの背後にある基本的な理論は、Shellによって生成されたプロセス(シェル組み込みではなく外部コマンドであると仮定)はfork()
およびexecve()
syscallsを介して作成され、その前に別のsyscall dup2()
は、execve()
が発生する前に必要なリダイレクトを実行します。その意味で、リダイレクトは親シェルから継承されます。 m&>n
およびm>n.txt
は、open()
およびdup2()
syscallの実行方法をシェルに通知します( 入力リダイレクトの仕組み 、 リダイレクトとパイプの違いは何ですか 、および 出力リダイレクトの意味と正確な意味 )
最も一般的なのは、 dash
(2>
にシンボリックリンクされている)やbash
など、 Bourneのようなシェル の/bin/sh
を介したものです。最初はデフォルトのPOSIX準拠のシェルで、もう1つはほとんどのユーザーが対話型セッションに使用するものです。構文と機能は異なりますが、幸いなことにエラーストリームリダイレクトは同じように機能します(&>
非標準のものを除く)。 cshとその派生物の場合、stderrリダイレクト そこではまったく機能しません。
2>
パートに戻りましょう。注目すべき2つの重要な点:>
はリダイレクト演算子を意味します。ここではファイルを開き、2
integerはstderrファイル記述子を表します。実際、これはまさにシェル言語のPOSIX標準が セクション2.7 でリダイレクトを定義する方法です。
[n]redir-op Word
単純な>
リダイレクトの場合、1
整数はstdout
に含まれます。つまり、echo Hello World > /dev/null
はecho Hello World 1>/dev/null
と同じです。整数またはリダイレクト演算子は引用符で囲まれないことに注意してください。そうしないと、シェルはそれらをそのように認識せず、代わりにテキストのリテラル文字列として扱います。間隔に関しては、整数がリダイレクト演算子のすぐ隣にあることが重要ですが、ファイルはリダイレクト演算子の隣でもそうでなくてもかまいません。つまり、command 2>/dev/null
とcommand 2> /dev/null
は問題なく動作します。
シェルの典型的なコマンドのやや単純化された構文は次のようになります
command [arg1] [arg2] 2> /dev/null
ここでのコツは、リダイレクトがどこにでも現れる可能性があることです。つまり、2> command [arg1]
とcommand 2> [arg1]
の両方が有効です。 bash
Shellには、stdoutストリームとstderrストリームの両方を同時にリダイレクトする&>
の方法がありますが、これもまたbash固有であり、スクリプトの移植性を求めている場合は機能しない可能性があります。 buntu Wiki および &>と2>&1の違いは何ですか も参照してください。
注:>
リダイレクト演算子はファイルを切り捨て、ファイルが存在する場合、上書きします。 2>>
は、stderr
をファイルに追加するために使用できます。
お気づきかもしれませんが、>
は単一のコマンドを意味します。スクリプトの場合、myscript.sh 2> /dev/null
のように外部からスクリプト全体のstderrストリームをリダイレクトするか、 exec built-in を使用できます。組み込みのexecには、いわば、対話的またはスクリプト経由で、シェルセッション全体のストリームを再配線する機能があります。何かのようなもの
#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file
この例では、ログファイルにstat: cannot stat '/etc/non_existing_file': No such file or directory
と表示されます。
さらに別の方法は、関数を使用することです。 kopciuszek の回答で述べたように、リダイレクトを既に付加した関数宣言を書くことができます。
some_function(){
command1
command2
} 2> my_log_file.txt
time
やstrace
などのコマンドは、デフォルトでそれらの出力をstderrに書き込みます。 time
コマンドの場合、唯一の実行可能な代替手段は、コマンド全体の出力をリダイレクトすることです。
time echo foo 2>&1 > file.txt
あるいは、出力を分離する場合は、同期リストまたはサブシェルをリダイレクトできます( related post に示すように)。
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
strace
やdialog
などの他のコマンドは、stderrをリダイレクトする手段を提供します。 strace
には、出力を書き込むファイル名を指定できる-o <filename.txt>
オプションがあります。 strace
が見る各サブプロセスのテキストファイルを書くためのオプションもあります。 dialog
コマンドは、テキストユーザーインターフェイスをstdoutに書き込みますが、stderrに出力します。したがって、 その出力を変数に保存します (var=$(...)
とパイプラインはstderrのみを受け取るため)には、ファイルをスワップする必要があります記述子
result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
しかし、さらに、--output-fd
フラグがあり、これも利用できます。名前付きパイプのメソッドもあります。何が起こっているかを完全に説明するには、dialog
コマンドに関するリンクされた投稿を読むことをお勧めします。