Linuxの中の2>&1は一体何ですか
Linuxでは
/dev/nullは空のデバイスファイル を表す0はstdin標準入力 を示す. 1はstdout標準出力 を示す.2はstderr標準エラー を表す.
実はこのコマンドは略語で、リダイレクトコマンドに対して
以上の
以上の解析により、
shellを
なぜ2>&1はcommand>1の後ろに書いて、直接2でいいですか.例えば
nohup command>/dev/null 2>&1 &
という形式の命令によく遭遇します.まず,この命令を大まかに分解すると,まずnohup
が現在のユーザとシステムの返信の下で,HUPメッセージに応答することを無視することを示す.&
は、このコマンドを後台のjobの形式で実行する.では、残りのcommand>/dev/null 2>&1
、command>/dev/null
はよく理解されています./dev/null
は空のデバイスを表しています.つまり、commandの実行結果は空のデバイスにリダイレクトされ、はっきり言って何も表示されません.では、2>&1
はどういう意味ですか.2>&1
いくつかの基本記号とその意味
command>/dev/nullから
実はこのコマンドは略語で、リダイレクトコマンドに対して
a > b
という形式に違いありません.command > /dev/null
はcommandがaの役割を果たし、/dev/nullがbの役割を果たしているのではないでしょうか.これは合理的に見えますが、実は1つのコマンドはaにならないに違いありません.commandが実行して生成した出力がaになるに違いありません.実は標準出力stdoutです.したがって、command > /dev/null
は、command 1 > /dev/null
が実行されたことに相当する.実行commandは、標準出力stdout(1で示す)を生成し、/dev/nullのデバイスファイルにリダイレクトします.2>&1
以上の
command > /dev/null
がcommand 1 > /dev/null
に等価であることで、2>&1
についてもよく理解できる.2は標準エラー、1は標準出力であり、このコマンドは標準エラーを標準出力にリダイレクトすることに相当するのではないか.待って&1ではなく、ここ&何ですか?ここで&
は、標準出力に相当する.ここはちょっとわかりにくいので、まず下を見てください.command>a 2>aとcommand>a 2>&1の違い
以上の解析により、
command>a 2>&1
というコマンドに対して、command 1>a 2>&1
と等価であり、commandによって生成された標準入力を実行してファイルaにリダイレクトし、標準エラーもファイルaにリダイレクトすると理解できる.では、command 1>a 2>&1
はcommand 1>a 2>a
に等しいのではないでしょうか.実はそうではありません.command 1>a 2>&1
とcommand 1>a 2>a
には違いがあります.違いは、前者は1回のファイルaしか開かず、後者は2回ファイルを開き、stdoutがstderrで上書きされることです.&1
の意味は、標準出力による参照と理解され、参照は、標準出力にリダイレクトして開いたaを生成することである.IO効率から言えば、command 1>a 2>&1
はcommand 1>a 2>a
よりも効率が高い.くりを一つあげる
shellを
//test.sh
#!/bin/sh
t
date
chmod +x test.sh
はtestである.sh実行権限を追加します.ここでは、tコマンドは存在せず、実行がエラーを報告し、stderrに出力する2つのコマンドを作成しました.dateは正常に実行され、実行は現在の時間を出力し、stdoutに出力されます../test.sh > res1.log
を実行した結果、stderrはres 1にリダイレクトされていないことが分かった.logではstderrが画面に印刷されます.これは、上記の./test.sh > res1.log
が./test.sh 1>res1.log
に等価であることをさらに証明している../test.sh>res2.log 2>&1
を実行した結果、stdoutとstderrはres 2にリダイレクトすることが分かった.ロゴが当たった.以上、stderr、すなわち2の出力方法について説明しなかったが、stderrは画面に出力され、ここではstdoutだけでなくres 2にリダイレクトする.logでは、res 2にリダイレクトするように標準エラーについても説明する.logの参照はres 2である.logのファイル記述子にあります.もう一度考えてみよう
なぜ2>&1はcommand>1の後ろに書いて、直接2でいいですか.例えば
ls 2>a
です.実はこの使い方も可能で、lsコマンドは現在のディレクトリをリストし、stdout(1)で表すと、このときstderr(2)がないため、このときls 2>a
を実行しても正常にaのファイルが生成されるが、aのファイルには空である.このときlsを実行してもstderr(2)は生成されないからである.