Linuxのstdin、stdout、およびstderrとは何ですか?
公開: 2022-01-29 stdin
、 stdout
、およびstderr
は、Linuxコマンドを起動したときに作成される3つのデータストリームです。 それらを使用して、スクリプトがパイプされているのかリダイレクトされているのかを判断できます。 その方法をお見せします。
ストリームが2つのポイントに参加
LinuxおよびUnixライクなオペレーティングシステムについて学び始めるとすぐに、 stdin
、 stdout
、およびstederr
という用語に出くわします。 これらは、Linuxコマンドの実行時に確立される3つの標準ストリームです。 コンピューティングでは、ストリームはデータを転送できるものです。 これらのストリームの場合、そのデータはテキストです。
水の流れのようなデータの流れには、2つの端があります。 それらには、ソースと流出があります。 使用しているLinuxコマンドは、各ストリームの一方の端を提供します。 もう一方の端は、コマンドを起動したシェルによって決定されます。 その端は、コマンドを起動したコマンドラインに従って、ターミナルウィンドウに接続されるか、パイプに接続されるか、ファイルまたは他のコマンドにリダイレクトされます。
Linux標準ストリーム
Linuxでは、 stdin
が標準入力ストリームです。 これは、入力としてテキストを受け入れます。 コマンドからシェルへのテキスト出力は、 stdout
(標準出力)ストリームを介して配信されます。 コマンドからのエラーメッセージは、 stderr
(標準エラー)ストリームを介して送信されます。
したがって、 stdout
とstderr
の2つの出力ストリームと、 stdin
の1つの入力ストリームがあることがわかります。 エラーメッセージと通常の出力にはそれぞれ、それらをターミナルウィンドウに運ぶための独自のコンジットがあるため、互いに独立して処理できます。
ストリームはファイルのように処理されます
Linuxのストリームは、他のほとんどすべてと同様に、ファイルであるかのように扱われます。 ファイルからテキストを読み取ったり、ファイルにテキストを書き込んだりできます。 これらのアクションは両方とも、データのストリームを含みます。 したがって、データのストリームをファイルとして処理するという概念は、それほど難しいものではありません。
プロセスに関連付けられた各ファイルには、プロセスを識別するための一意の番号が割り当てられます。 これはファイル記述子として知られています。 ファイルに対してアクションを実行する必要がある場合は常に、ファイル記述子を使用してファイルを識別します。
これらの値は、常にstdin
、 stdout,
およびstderr
に使用されます。
- 0 :stdin
- 1 :stdout
- 2 :stderr
パイプとリダイレクトへの反応
誰かが主題を簡単に紹介できるようにするための一般的な手法は、トピックの簡略化されたバージョンを教えることです。 たとえば、文法では、ルールは「Cの後を除いてEの前にI」であると言われます。 しかし実際には、この規則に従う場合よりも多くの例外があります。
同様に、 stdin
、 stdout
、およびstderr
について話すときは、プロセスが3つの標準ストリームがどこで終了するかを知らず、気にしないという受け入れられた公理を取り除くのが便利です。 プロセスは、その出力が端末に送られるのか、ファイルにリダイレクトされるのかを気にする必要がありますか? 入力がキーボードからのものなのか、別のプロセスからパイプされているのかさえわかりますか?
実際、プロセスは認識しており、少なくともチェックすることを選択した場合はそれを見つけることができます。ソフトウェアの作成者がその機能を追加することを決定した場合、プロセスはそれに応じて動作を変更できます。
この振る舞いの変化は非常に簡単にわかります。 次の2つのコマンドを試してください。
ls
ls | 猫
ls
コマンドは、その出力( stdout
)が別のコマンドにパイプされている場合、動作が異なります。 単一列の出力に切り替わるのはls
であり、 cat
によって実行される変換ではありません。 また、出力がリダイレクトされている場合、 ls
は同じことを行います。
ls> capture.txt
catcapture.txt
stdoutとstderrのリダイレクト
専用ストリームによってエラーメッセージが配信されることには利点があります。 これは、コマンドの出力( stdout
)をファイルにリダイレクトしても、ターミナルウィンドウにエラーメッセージ( stderr
)が表示されることを意味します。 必要に応じて、エラーが発生したときに対応できます。 また、 stdout
がリダイレクトされたファイルをエラーメッセージが汚染するのを防ぎます。
次のテキストをエディターに入力し、error.shというファイルに保存します。
#!/ bin / bash echo "存在しないファイルにアクセスしようとしています" 猫bad-filename.txt
次のコマンドでスクリプトを実行可能にします。
chmod + x error.sh
スクリプトの最初の行は、 stdout
ストリームを介してテキストをターミナルウィンドウにエコーします。 2行目は、存在しないファイルにアクセスしようとします。 これにより、 stderr
を介して配信されるエラーメッセージが生成されます。
次のコマンドでスクリプトを実行します。
./error.sh
stdout
とstderr
の両方の出力ストリームがターミナルウィンドウに表示されていることがわかります。
出力をファイルにリダイレクトしてみましょう。
./error.sh> Capture.txt
stderr
を介して配信されるエラーメッセージは、引き続きターミナルウィンドウに送信されます。 ファイルの内容をチェックして、 stdout
出力がファイルに送信されたかどうかを確認できます。
catcapture.txt
stdin
からの出力は、期待どおりにファイルにリダイレクトされました。
>
リダイレクト記号は、デフォルトでstdout
で機能します。 数値ファイル記述子の1つを使用して、リダイレクトする標準出力ストリームを指定できます。
stdout
を明示的にリダイレクトするには、次のリダイレクト命令を使用します。
1>
stderr
を明示的にリダイレクトするには、次のリダイレクト命令を使用します。
2>
もう一度テストしてみましょう。今回は2>
:を使用します。
./error.sh 2> Capture.txt
エラーメッセージがリダイレクトされ、 stdout
echo
メッセージがターミナルウィンドウに送信されます。
Capture.txtファイルの内容を見てみましょう。
catcapture.txt
stderr
メッセージは期待どおりcapture.txtにあります。
stdoutとstderrの両方をリダイレクトする
確かに、 stdout
またはstderr
のいずれかを互いに独立してファイルにリダイレクトできる場合は、両方を同時に2つの異なるファイルにリダイレクトできるはずですか?
はい、できます。 このコマンドは、 stdout
をcapture.txtというファイルに転送し、 stderr
をerror.txtというファイルに転送します。
./error.sh 1> Capture.txt 2> error.txt
出力のストリーム(標準出力と標準エラー)の両方がファイルにリダイレクトされるため、ターミナルウィンドウに表示される出力はありません。 何も起こらなかったかのように、コマンドラインプロンプトに戻ります。
各ファイルの内容を確認してみましょう。
catcapture.txt
cat error.txt
stdoutとstderrを同じファイルにリダイレクトする
これはすばらしいことです。各標準出力ストリームは、専用のファイルに送られます。 私たちができる他の唯一の組み合わせは、 stdout
とstderr
の両方を同じファイルに送信することです。
これは、次のコマンドで実現できます。
./error.sh> Capture.txt 2>&1
それを分解しましょう。
- ./error.sh:error.shスクリプトファイルを起動します。
- > Capture.txt :
stdout
ストリームをcapture.txtファイルにリダイレクトします。>
は1>
の省略形です。 - 2>&1 :これは&>リダイレクト命令を使用します。 この命令を使用すると、あるストリームを別のストリームと同じ宛先に到達させるようにシェルに指示できます。 この場合、「ストリーム2、
stderr
を、ストリーム1、stdout
がリダイレクトされているのと同じ宛先にリダイレクトする」と言っています。
目に見える出力はありません。 それは励みになります。
Capture.txtファイルをチェックして、その内容を確認しましょう。
catcapture.txt
stdout
ストリームとstderr
ストリームの両方が単一の宛先ファイルにリダイレクトされています。
ストリームの出力をリダイレクトしてサイレントに破棄するには、出力を/dev/null
に転送します。
スクリプト内のリダイレクトの検出
コマンドがストリームのいずれかがリダイレクトされているかどうかを検出し、それに応じてその動作を変更する方法を説明しました。 独自のスクリプトでこれを達成できますか? はい、できます。 そして、それは理解して採用するのが非常に簡単なテクニックです。
次のテキストをエディターに入力し、input.shとして保存します。
#!/ bin / bash if [-t 0]; それから キーボードからのechostdin それ以外 パイプまたはファイルからのechostdin fi
次のコマンドを使用して、実行可能にします。
chmod + x input.sh
賢い部分は角括弧内のテストです。 -t
(ターミナル)オプションは、ファイル記述子に関連付けられたファイルがターミナルウィンドウで終了した場合にtrue(0)を返します。 stdin
を表すテストの引数としてファイル記述子0を使用しました。
stdin
がターミナルウィンドウに接続されている場合、テストは真であることが証明されます。 stdin
がファイルまたはパイプに接続されている場合、テストは失敗します。
便利なテキストファイルを使用して、スクリプトへの入力を生成できます。 ここでは、dummy.txtという名前を使用しています。
./input.sh <dummy.txt
出力は、入力がキーボードからではなく、ファイルからのものであることをスクリプトが認識していることを示しています。 必要に応じて、スクリプトの動作を変更できます。
それはファイルリダイレクトでした。パイプで試してみましょう。
猫dummy.txt | ./input.sh
スクリプトは、入力がパイプされていることを認識します。 または、より正確には、 stdin
ストリームがターミナルウィンドウに接続されていないことをもう一度認識します。
パイプもリダイレクトも使用せずにスクリプトを実行してみましょう。
./input.sh
stdin
ストリームはターミナルウィンドウに接続されており、スクリプトはそれに応じてこれを報告します。
出力ストリームで同じことを確認するには、新しいスクリプトが必要です。 エディターに次のように入力し、output.shとして保存します。
#!/ bin / bash if [-t 1]; それから エコーstdoutはターミナルウィンドウに行きます それ以外 echostdoutがリダイレクトまたはパイプされています fi
次のコマンドを使用して、実行可能にします。
chmod + x input.sh
このスクリプトに対する唯一の重要な変更は、角括弧内のテストです。 stdout
のファイル記述子を表すために数字1を使用しています。
試してみましょう。 cat
を介して出力をパイプします。
./output | 猫
スクリプトは、その出力がターミナルウィンドウに直接送信されないことを認識します。
出力をファイルにリダイレクトすることで、スクリプトをテストすることもできます。
./output.sh> Capture.txt
ターミナルウィンドウへの出力はありません。コマンドプロンプトに静かに戻ります。 予想通り。
Capture.txtファイルの内部を調べて、何がキャプチャされたかを確認できます。 これを行うには、次のコマンドを使用します。
猫capture.sh
この場合も、スクリプトの簡単なテストで、 stdout
ストリームがターミナルウィンドウに直接送信されていないことが検出されます。
パイプやリダイレクトを使用せずにスクリプトを実行すると、 stdout
がターミナルウィンドウに直接配信されていることが検出されます。
./output.sh
そしてそれはまさに私たちが見ているものです。
意識の流れ
スクリプトがターミナルウィンドウまたはパイプに接続されているか、リダイレクトされているかを判断する方法を知っていると、それに応じてスクリプトの動作を調整できます。
ロギングと診断出力は、画面に表示されるかファイルに表示されるかに応じて、多かれ少なかれ詳細になります。 エラーメッセージは、通常のプログラム出力とは異なるファイルに記録される可能性があります。
通常の場合と同様に、知識が増えると選択肢も増えます。
Linuxコマンド | ||
ファイル | tar・pv・cat・tac・chmod・grep・diff・sed・ar・man・pushd・popd・fsck・testdisk・seq・fd・pandoc・cd・$ PATH・awk・join・jq・fold・uniq・journalctl・tail・stat・ls・fstab・echo・less・chgrp・chown・rev・look・strings・type・rename・zip・unzip・mount・umount・install・fdisk・mkfs・rm・rmdir・rsync・df・gpg・vi・nano・mkdir・du・ln・patch・convert・rclone・shred・srm | |
プロセス | エイリアス・screen・top・nice・renice・progress・strace・systemd・tmux・chsh・history・at・batch・free・which・dmesg・chfn・usermod・ps・chroot・xargs・tty・pinky・lsof・vmstat・タイムアウト・wall・yes・kill・sleep・sudo・su・time・groupadd・usermod・groups・lshw・shutdown・reboot・halt・poweroff・passwd・lscpu・crontab・date・bg・fg | |
ネットワーキング | netstat・ping・traceroute・ip・ss・whois・fail2ban・bmon・dig・finger・nmap・ftp・curl・wget・who・whoami・w・iptables・ssh-keygen・ufw |
関連:開発者と愛好家のための最高のLinuxラップトップ