Bashスクリプト:開始
Bashスクリプト、パート2:ループ
Bashスクリプト、パート3:オプションとコマンドラインスイッチ
Bashスクリプト、パート4:入力と出力
Bashスクリプト、パート5:シグナル、バックグラウンドタスク、スクリプト管理
Bashスクリプト、パート6:関数とライブラリーの開発
Bashスクリプト、パート7:sedとワープロ
Bashスクリプト、パート8:awkデータ処理言語
Bashスクリプトパート9:正規表現
Bashスクリプト、パート10:ケーススタディ
Bashスクリプト、パート11:対話型ユーティリティの期待と自動化
前回、この一連のbashスクリプト資料の第3部では、コマンドラインオプションとキーについて説明しました。 今日のトピックは、入力、出力、およびそれに関連するすべてのものです。

コマンドラインスクリプトの出力を操作する2つの方法に既に慣れています。
- 画面に出力データを表示します。
 - 出力をファイルにリダイレクトします。
 
画面に何かを表示してファイルに何かを書き込む必要がある場合があるため、Linuxでの入出力の処理方法を理解する必要があります。つまり、必要な場所にスクリプトの結果を送信する方法を学習する必要があります。 まず、標準のファイル記述子について説明します。
標準ファイル記述子
Linux上のすべてのものは、入出力を含むファイルです。 オペレーティングシステムは、記述子を使用してファイルを識別します。
各プロセスは、最大9個のファイル記述子を開くことができます。 bashシェルは、識別子0、1、および2の最初の3つの記述子を予約します。これは、それらが意味するものです。
0 、 STDIN —標準入力ストリーム。1 、 STDOUT —標準出力ストリーム。2 、 STDERR —標準エラーストリーム。
これらの3つの特別な記述子は、スクリプト内のデータの入出力を処理します。
標準スレッドを適切に理解する必要があります。 それらは、スクリプトが外の世界と相互作用する基盤と比較することができます。 それらについての詳細を検討してください。
スタディン
STDIN —標準のシェル入力ストリームです。 端末の場合、標準入力はキーボードです。 スクリプトが入力リダイレクト文字- 
<使用する場合、Linuxは標準入力ファイル記述子をコマンドで指定されたものに置き換えます。 システムはファイルを読み取り、キーボードから入力されたかのようにデータを処理します。
コマンドラインでデータを取得するファイルが指定されていない場合、多くのbashコマンドは
STDINからの入力を受け入れます。 たとえば、これは
cat当てはまります。
パラメーターを指定せずにコマンドラインで
catコマンドを入力すると、 
STDINからの入力を受け入れ
STDIN 。 次の行を入力すると、 
cat単にそれを画面に表示します。
標準出力
STDOUT —標準シェル出力ストリーム。 デフォルトでは、これが画面です。 ほとんどのbashコマンドは、データを
STDOUTに出力し
STDOUT 。これにより、コンソールに表示されます。 データをそのコンテンツに添付することでファイルにリダイレクトできます。これには
>>コマンドが使用されます。
したがって、このコマンドで他のデータを追加できるデータファイルがあります。
 pwd >> myfile 
どの
pwdが
myfileファイルに追加されますが、既にその中にあるデータはどこにも行きません。
コマンド出力をファイルにリダイレクトするこれまでのところ、すべては問題ありませんが、存在しない
xfileファイルを参照して以下に示すような処理を行おうと
xfileと、 
myfileファイルにエラーメッセージ
xfileされる
xfileになります。
 ls –l xfile > myfile 
このコマンドを実行すると、画面にエラーメッセージが表示されます。
存在しないファイルにアクセスしようとしています存在しないファイルにアクセスしようとするとエラーが生成されますが、シェルはエラーメッセージをファイルにリダイレクトせず、画面に表示しました。 ただし、エラーメッセージをファイルに送信する必要がありました。 どうする 答えは簡単です-3番目の標準記述子を使用します。
ステダー
STDERRは、シェルエラーの標準ストリームです。 デフォルトでは、この記述子は
STDOUT示すものと同じことを示しているため、エラーが発生すると画面にメッセージが表示されます。
したがって、エラーメッセージを画面に表示するのではなく、たとえばログファイルなどにリダイレクトする必要があるとします。
▍エラーフローのリダイレクト
既にご存じのように、ファイル記述子
STDERR — 2 
STDERR — 。リダイレクトコマンドの前にこの記述子を配置することにより、エラーをリダイレクトできます。
 ls -l xfile 2>myfile cat ./myfile 
エラーメッセージは
myfileます。
エラーメッセージをファイルにリダイレクトするerrorエラーおよび出力ストリームのリダイレクト
コマンドラインスクリプトを記述するとき、エラーメッセージのリダイレクトと標準出力のリダイレクトの両方を整理する必要がある場合があります。 これを実現するために、ファイルで対応する記述子に対してリダイレクトコマンドを使用する必要があります。エラーおよび標準出力は次の場所に移動する必要があります。
 ls –l myfile xfile anotherfile 2> errorcontent 1> correctcontent 
エラーのリダイレクトと標準出力シェルは、 
1>構造のおかげで、 
ls通常
STDOUTに送信するものを
correctcontentファイルに
correctcontentます。 
STDERR分類されるエラーメッセージは、リダイレクトコマンド
2>ために
errorcontentファイルに表示されます。
必要に応じて、 
&>コマンドを使用して、 
STDERRと
STDOUT両方を同じファイルにリダイレクトできます。
STDERRとSTDOUTを同じファイルにリダイレクトするコマンドを実行すると、 
STDERRおよび
STDOUTが
contentファイルに表示されます。
スクリプト出力のリダイレクト
コマンドラインスクリプトで出力をリダイレクトするには、2つの方法があります。
- 一時的なリダイレクト、または1行の出力のリダイレクト。
 - 永続的なリダイレクト、またはスクリプトまたはその一部のすべての出力のリダイレクト。
 
▍一時的な出力リダイレクト
スクリプトでは、1行の出力を
STDERRリダイレクトできます。 これを行うには、 
STDERR記述子を指定してリダイレクトコマンドを使用するだけで十分ですが、記述子番号の前にアンパサンド( 
& )記号を配置する必要があります。
 #!/bin/bash echo "This is an error" >&2 echo "This is normal output" 
スクリプトを実行すると、デフォルトのエラーが通常のデータと同じ場所に出力されるため、両方の行が画面に表示されます。
一時的なリダイレクトSTDERRの出力がファイルに
STDERRするようにスクリプトを実行します。
 ./myscript 2> myfile 
ご覧のとおり、通常の出力がコンソールに対して行われ、エラーメッセージがファイルに表示されます。
エラーメッセージはファイルに書き込まれます。▍永続的な出力リダイレクト
スクリプトが画面に表示される多くのデータをリダイレクトする必要がある場合、各
echoコールに適切なコマンドを追加するのは不便です。 代わりに、 
execコマンドを使用して、スクリプトの実行中に特定の記述子にリダイレクトされるように出力を設定できます。
 #!/bin/bash exec 1>outfile echo  echo  echo  
スクリプトを実行します。
すべての出力をファイルにリダイレクトする出力リダイレクトコマンドで指定されたファイルを見ると、 
echoコマンドによって出力されたすべてのものがこのファイルに分類されていることが
echoます。
execコマンドは、スクリプトの先頭だけでなく、他の場所でも使用できます。
 #!/bin/bash exec 2>myerror echo  echo  exec 1>myfile echo  echo  >&2 
これは、スクリプトを実行し、出力のリダイレクト先のファイルを表示した後に発生します。
出力を異なるファイルにリダイレクトするexecコマンドは、最初に
STDERRからの出力を
myerrorファイルに
myerrorます。 次に、いくつかの
echoコマンドの出力が
STDOUT送信され、表示されます。 その後、 
execコマンドが
STDOUTに入ったものを
myfileファイルに送信し、最後に
echoコマンドで
STDERRへのリダイレクトコマンドを使用します
myerror.これにより、 
myerror.ファイルに対応する行が
myerror.ます
myerror.これをマスターしたら、出力を必要な場所にリダイレクトできます。 次に、入力のリダイレクトについて説明します。
スクリプト入力のリダイレクト
入力をリダイレクトするには、出力のリダイレクトに使用したのと同じ手法を使用できます。 たとえば、 
execコマンドを使用すると、 
STDINデータソースをファイルにできます。
 exec 0< myfile 
このコマンドは、入力ソースが通常の
STDINではなく
myfileであることをシェルに伝え
STDIN 。 実際の入力リダイレクトを見てみましょう。
 #!/bin/bash exec 0< testfile count=1 while read line do echo "Line #$count: $line" count=$(( $count + 1 )) done 
これは、スクリプトの実行後に画面に表示されるものです。
入力リダイレクト前の記事で、 
readコマンドを使用してキーボードからユーザー入力を読み取る方法を学びました。 入力をリダイレクトしてファイルをデータソースにすると、 
STDINからデータを読み取ろうとすると、キーボードからではなくファイルから
readコマンドが読み取られ
STDIN 。
一部のLinux管理者は、このアプローチを使用してログファイルを読み取り、その後処理します。
独自の出力リダイレクトを作成する
スクリプトの入力と出力をリダイレクトすることにより、3つの標準ファイル記述子に制限されません。 既に述べたように、最大9つのオープン記述子を使用できます。 残りの6つは3〜8の数字で、入力または出力のリダイレクトに使用できます。 それらのいずれもファイルに割り当てて、スクリプトコードで使用できます。
execコマンドを使用して、出力にハンドルを割り当てることができます。
 #!/bin/bash exec 3>myfile echo  echo  >&3 echo  
スクリプトの実行後、出力の一部は画面に、一部は記述子
3ファイルに移動します。
ネイティブ記述子を使用した出力のリダイレクトデータ入力用のファイル記述子の作成
スクリプトは、出力と同じ方法で入力をリダイレクトできます。 データエントリをリダイレクトする前に、 
STDINを別の記述子に保存し
STDIN 。
ファイルを読み取った後、 
STDINを復元して通常どおり使用でき
STDIN 。
 #!/bin/bash exec 6<&0 exec 0< myfile count=1 while read line do echo "Line #$count: $line" count=$(( $count + 1 )) done exec 0<&6 read -p "Are you done now? " answer case $answer in y) echo "Goodbye";; n) echo "Sorry, this is the end.";; esac 
スクリプトをテストしましょう。
入力リダイレクトこの例では、 
STDINへの参照を保存するためにファイル記述子6が使用されました。 その後、入力がリダイレクトされ、ファイルが
STDINデータソースになりました。 その後、 
readコマンドの入力は、リダイレクトされた
STDIN 、つまりファイルから
STDINれました。
ファイルを読み取った後、 
STDINを元の状態に戻し、記述子
6リダイレクトします。 ここで、すべてが正しく機能することを確認するために、スクリプトはユーザーに質問をし、キーボード入力を待機し、入力内容を処理します。
ファイル記述子を閉じる
スクリプトの終了後、シェルはファイル記述子を自動的に閉じます。 ただし、場合によっては、スクリプトの動作が完了する前に記述子を手動で閉じる必要があります。 記述子を閉じるには、 
&-リダイレクトする必要があります。 次のようになります。
 #!/bin/bash exec 3> myfile echo "This is a test line of data" >&3 exec 3>&- echo "This won't work" >&3 
スクリプトの実行後、エラーメッセージが表示されます。
プライベートファイル記述子へのアクセスの試行問題は、存在しない記述子にアクセスしようとしたことです。
スクリプトでファイル記述子を閉じるときは注意してください。 データをファイルに送信してからハンドルを閉じてから再度開くと、シェルは既存のファイルを新しいファイルに置き換えます。 つまり、以前にこのファイルに書き込まれたものはすべて失われます。
オープン記述子に関する情報の取得
Linuxで開いているすべての記述子のリストを取得するには、 
lsofコマンドを使用できます。 Fedoraなどの多くのディストリビューションでは、 
lsofユーティリティは
/usr/sbinます。 このコマンドは、システムで開いている各記述子に関する情報を表示するため、非常に便利です。 これには、バックグラウンドで実行されているプロセスが発見したもの、およびログインしているユーザーが開いているものが含まれます。
このコマンドには多くのキーがあります。最も重要なキーを検討してください。
-pプロセスID指定しID 。-d情報が必要な記述子の番号を指定できます。
現在のプロセスの
PIDを調べるには、シェルが現在の
PID書き込む特別な環境変数
$$使用できます。
-aスイッチは、他の2つのキーを使用して返された結果に対して論理
演算を実行するために使用されます。
 lsof -a -p $$ -d 0,1,2 
オープン記述子情報の表示STDIN 、 
STDOUTおよび
STDERR —関連付けられているファイルのタイプ
STDERR — CHR(文字モード)です。 それらはすべて端末を指すため、ファイル名は端末に割り当てられたデバイスの名前と一致します。 3つの標準ファイルはすべて読み取りおよび書き込み可能です。
標準のスクリプトに加えて、他の記述子が開かれているスクリプトから
lsofを呼び出してみましょう。
 #!/bin/bash exec 3> myfile1 exec 6> myfile2 exec 7< myfile3 lsof -a -p $$ -d 0,1,2,3,6,7 
このスクリプトを実行すると、次のようになります。
スクリプトによって開かれたファイル記述子を表示するスクリプトは、出力用に2つの記述子( 
3および
6 )と入力用に1つ( 
7 )を開きました。 記述子の構成に使用されるファイルへのパスもここに示されています。
出力抑制
たとえば、バックグラウンドプロセスとして実行できるスクリプトのコマンドが画面に何も表示されないようにする必要がある場合があります。 これを行うには、出力を
/dev/nullリダイレクトでき
/dev/null 。 それは一種のブラックホールです。
ここで、たとえば、エラーメッセージの出力を抑制する方法:
 ls -al badfile anotherfile 2> /dev/null 
たとえば、ファイルを削除せずにクリアする必要がある場合、同じアプローチが使用されます。
 cat /dev/null > myfile 
まとめ
今日は、コマンドラインスクリプトで入力と出力がどのように機能するかを学びました。 これで、ファイル記述子を処理、作成、表示、および閉じることができ、入力、出力、およびエラーストリームのリダイレクトについて理解できました。 これらはすべて、bashスクリプトの開発において非常に重要です。
次回は、Linuxシグナル、スクリプトでそれらを処理する方法、スケジュールされたタスクの実行、およびバックグラウンドタスクについて説明します。
親愛なる読者! この資料は、入力、出力、およびエラーストリームの操作の基本を提供します。 私たちはあなたの中に、経験のみによってもたらされるすべてのことを話すことができる専門家がいると確信しています。 もしそうなら-あなたに言葉を渡します。
