技術ノート Linux Linux の stdin、stdout、stderr とは何ですか?

Linux の stdin、stdout、stderr とは何ですか?

重要なポイント

  • Linux コマンドは、コマンドに関するデータの転送に使用できる 3 つのデータ ストリーム (stdin、stdout、および stderr) を作成します。
  • Linux では、stdin は入力ストリーム、stdout は出力ストリーム、stderr はエラー ストリームです。
  • リダイレクトを使用すると、出力またはエラーをファイルやパイプなどの別の宛先にリダイレクトできます。

stdin stdout 、および stderr 、Linux コマンドの起動時に作成される 3 つのデータ ストリームです。これらを使用すると、スクリプトがパイプ処理されているかリダイレクトされているかを知ることができます。その方法をご紹介します。

ストリームは 2 つの点を結合します

Linux や Unix 系オペレーティング システムについて学び始めるとすぐに、 stdin stdout 、および stederr という用語に遭遇するでしょう。これらは、Linux コマンドの実行時に確立される 3 つの標準ストリーム です。コンピューティングにおいて、ストリームとはデータを転送できるものです。これらのストリームの場合、そのデータはテキストです。

データ ストリームには、水の流れと同様に 2 つの端があります。それらにはソースと流出があります。使用している Linux コマンドはいずれも、各ストリームの一端を提供します。もう一方の端は、コマンドを起動したシェルによって決まります。その端は、コマンドを起動したコマンド ラインに応じて、ターミナル ウィンドウに接続されるか、パイプに接続されるか、ファイルまたは他のコマンドにリダイレクトされます。

Linux の stdin、stdout、stderr とは何ですか?

Linux 標準ストリーム: stdin、stdout、stderr

Linux では、 stdin が標準入力ストリームです。これはテキストを入力として受け入れます。コマンドからシェルへのテキスト出力は、 stdout (標準出力) ストリーム経由で配信されます。コマンドからのエラー メッセージは、 stderr (標準エラー) ストリームを通じて送信されます。

したがって、2 つの出力ストリーム stdout stderr と 1 つの入力ストリーム stdin があることがわかります。エラー メッセージと通常の出力にはそれぞれ、ターミナル ウィンドウに送信するための独自のコンジットがあるため、相互に独立して処理できます。

Linux の stdin、stdout、stderr とは何ですか?

ストリームはファイルと同様に処理されます

Linux のストリームは、他のほとんどすべてのものと同様に、ファイルであるかのように扱われます。ファイルからテキストを読み取ることも、ファイルにテキストを書き込むこともできます。これらのアクションには両方ともデータのストリームが関係します。したがって、データのストリームをファイルとして処理するという概念は、それほど無理のあるものではありません。

プロセスに関連付けられた各ファイルには、それを識別するための一意の番号が割り当てられます。これはファイル記述子として知られています。ファイルに対してアクションを実行する必要がある場合は常に、 ファイル記述子を 使用してファイルを識別します。

これらの値は、 stdin stdout, および stderr に常に使用されます。

  • 0: 標準入力
  • 1: 標準出力
  • 2: 標準エラー
Linux の stdin、stdout、stderr とは何ですか?

パイプとリダイレクトへの反応

主題への入門を容易にするための一般的なテクニックは、その主題の簡略化されたバージョンを教えることです。たとえば、文法では、「E の前には I、C の後は除く」というルールがあると言われます。しかし実際には、 この規則に従うケースよりも例外の方が多いのです

同様に、 stdin stdout 、および stderr について話すとき、プロセスは 3 つの標準ストリームがどこで終了するかは知らないし気にもしない、という一般に受け入れられている公理を持ち出すのが便利です。プロセスは、その出力が端末に送られるのか、それともファイルにリダイレクトされるのかを気にする必要があるでしょうか?入力がキーボードから来ているのか、それとも別のプロセスからパイプで入力されているのかさえわかりますか?

実際、プロセスは知っています — あるいは、チェックすることを選択した場合には少なくとも知ることができます — そして、ソフトウェア作成者がその機能を追加することを決定した場合には、それに応じて動作を変更できます。

この行動の変化は非常に簡単に確認できます。次の 2 つのコマンドを試してください。

 ls

 ls |猫

ls コマンドの出力 ( stdout ) が別のコマンドにパイプされる場合、 ls コマンドの動作は異なります。単一列出力に切り替えるのは ls であり、 cat によって実行される変換ではありません。そして、出力がリダイレクトされている場合、 ls 同じことを行います。

 ls > キャプチャ.txt

猫の捕獲.txt 

Linux の stdin、stdout、stderr とは何ですか?

stdout と stderr のリダイレクト

エラー メッセージを専用のストリームで配信することには利点があります。これは、コマンドの出力 ( stdout ) をファイルにリダイレクトしても、ターミナル ウィンドウにエラー メッセージ ( stderr ) が表示されることを意味します。必要に応じて、エラーが発生したときに対処できます。また、エラー メッセージが stdout 出力のリダイレクト先のファイルを汚染することも防ぎます。

次のテキストをエディタに入力し、error.sh というファイルに保存します。

 #!/bin/bash
echo "About to try to access a file that doesn't exist"
cat bad-filename .txt

次のコマンドを使用してスクリプトを実行可能にします。

 chmod +x エラー.sh

スクリプトの最初の行は、 stdout ストリーム経由でテキストを端末ウィンドウにエコーします。 2 行目は、存在しないファイルへのアクセスを試行します。これにより、 stderr 経由で配信されるエラー メッセージが生成されます。

次のコマンドでスクリプトを実行します。

 ./error.sh

出力ストリーム stdout stderr が両方とも端末ウィンドウに表示されていることがわかります。

出力をファイルにリダイレクトしてみましょう。

 ./error.sh > Capture.txt

stderr 経由で配信されるエラー メッセージは、引き続きターミナル ウィンドウに送信されます。ファイルの内容をチェックして、 stdout 出力がファイルに送信されたかどうかを確認できます。

猫の捕獲.txt

stdin からの出力は期待どおりにファイルにリダイレクトされました。

> リダイレクト シンボルは、デフォルトで stdout で機能します。数値ファイル記述子の 1 つを使用して、どの標準出力ストリームをリダイレクトするかを指定できます。

stdout を明示的にリダイレクトするには、次のリダイレクト命令を使用します。

 1>

stderr を明示的にリダイレクトするには、次のリダイレクト命令を使用します。

 2>

もう一度テストしてみましょう。今回は 2> 使用します。

 ./error.sh 2> キャプチャ.txt

エラー メッセージはリダイレクトされ、 stdout echo メッセージが端末ウィンドウに送信されます。

Capture.txt ファイルの内容を見てみましょう。

猫の捕獲.txt

stderr メッセージは、予想どおり、capture.txt にあります。

Linux の stdin、stdout、stderr とは何ですか?

stdout と stderr の両方をリダイレクトする

確かに、 stdout または stderr を互いに独立してファイルにリダイレクトできる場合、両方を同時に 2 つの異なるファイルにリダイレクトできるはずです。

はい、できます。このコマンドは、 stdout Capture.txt というファイルに送信し、 stderr error.txt というファイルに送信します。

 ./error.sh 1> Capture.txt 2> error.txt

標準出力と標準エラーの両方の出力ストリームがファイルにリダイレクトされるため、ターミナル ウィンドウには出力が表示されません。何も起こらなかったかのようにコマンド ライン プロンプトに戻ります。

各ファイルの内容を確認してみましょう。

猫の捕獲.txt

猫のエラー.txt 

Linux の stdin、stdout、stderr とは何ですか?

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 ファイルをチェックして、その内容を確認してみましょう。

猫の捕獲.txt

stdout stderr ストリームの両方が 1 つの宛先ファイルにリダイレクトされました。

ストリームの出力をリダイレクトしてサイレントに破棄するには、出力を /dev/null に送信します。

スクリプト内のリダイレクトの検出

いずれかのストリームがリダイレクトされているかどうかをコマンドがどのように検出し、それに応じて動作を変更するかを選択できる方法について説明しました。独自のスクリプトでこれを実現できますか?はい、できます。そして、それは理解して採用するのが非常に簡単なテクニックです。

次のテキストをエディタに入力し、input.sh として保存します。

 #!/bin/bash
if [ -t 0 ] ; then
echo stdin coming from keyboard
else echo stdin coming from a pipe or a file
fi

次のコマンドを使用して実行可能にします。

 chmod +x input.sh

賢い部分は 角括弧内のテスト です。ファイル記述子に関連付けられたファイルが ターミナル ウィンドウで終了する 場合、 -t (ターミナル) オプションは true (0) を返します。ファイル記述子 0 をテストの引数として使用しました。これは stdin を表します。

stdin 端末ウィンドウに接続されている場合、テストは true であることがわかります。 stdin ファイルまたはパイプに接続されている場合、テストは失敗します。

便利なテキスト ファイルを使用して、スクリプトへの入力を生成できます。ここでは、dummy.txt というファイルを使用しています。

 ./input.sh < ダミー.txt

出力は、入力がキーボードからではなくファイルから来ていることをスクリプトが認識していることを示しています。必要に応じて、スクリプトの動作をそれに応じて変更できます。

これはファイル リダイレクトを使用したものでした。パイプを使用して試してみましょう。

猫のダミー.txt | ./input.sh

スクリプトは、入力がパイプされていることを認識します。より正確に言えば、 stdin ストリームが端末ウィンドウに接続されていないことを再度認識します。

パイプもリダイレクトも使用せずにスクリプトを実行してみましょう。

 ./input.sh

stdin ストリームはターミナル ウィンドウに接続され、スクリプトはそれに応じてこれを報告します。

出力ストリームで同じことを確認するには、新しいスクリプトが必要です。エディターに次を入力し、output.sh として保存します。

 #!/bin/bash
if [ -t 1 ] ; then
echo stdout is going to the terminal window
else
echo stdout is being redirected or piped
fi

次のコマンドを使用して実行可能にします。

 chmod +x input.sh

このスクリプトに対する唯一の重要な変更は、角括弧内のテストです。 stdout のファイル記述子を表すために数字 1 を使用しています。

試してみましょう。出力を cat 経由でパイプ処理します。

 ./出力 |猫

スクリプトは、その出力が端末ウィンドウに直接送信されないことを認識します。

出力をファイルにリダイレクトしてスクリプトをテストすることもできます。

 ./output.sh > Capture.txt

ターミナル ウィンドウには何も出力されず、何も言わずにコマンド プロンプトに戻ります。予想どおりです。

Capture.txt ファイル内を調べて、何がキャプチャされたかを確認できます。これを行うには、次のコマンドを使用します。

猫の捕獲.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 · パッチ · 変換 · rclone · シュレッド · srm · scp · gzip · chattr · カット · 検索 · umask · wc · tr

プロセス

エイリアス · スクリーン · トップ · ナイス · renice · 進行状況 · strace · systemd · tmux · chsh · 履歴 · at · バッチ · フリー · what · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · タイムアウト · ウォール · はい · キル · スリープ · sudo · su · タイム · groupadd · usermod · グループ · lshw · シャットダウン · 再起動 · 停止 · パワーオフ · パスワード · lscpu · crontab · 日付 · bg · fg · pidof · nohup · pmap

ネットワーキング

netstat ping ip ss whois fail2ban bmon dig finger nmap ftp curl wget who whoami w iptables ssh-keygen ufw arping firewalld

「 Linux の stdin、stdout、stderr とは何ですか?」に関するベスト動画選定!

【Linuxの基礎#1】Linuxの基礎の概要
【LinuC/LPIC合格講座】Linuxの起動とシャットダウンを完全理解【ITエンジニア基礎入門】#4