Bashスクリプト、パート4:入力と出力

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つの記述子を予約します。これは、それらが意味するものです。





これらの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行の出力を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 "This is a test of redirecting all output" echo "from a shell script to another file." echo "without having to redirect every line"
      
      





スクリプトを実行します。









すべての出力をファイルにリダイレクトする



出力リダイレクトコマンドで指定されたファイルを見ると、 echo



コマンドによって出力されたすべてのものがこのファイルに分類されていることがecho



ます。



exec



コマンドは、スクリプトの先頭だけでなく、他の場所でも使用できます。



 #!/bin/bash exec 2>myerror echo "This is the start of the script" echo "now redirecting all output to another location" exec 1>myfile echo "This should go to the myfile file" echo "and this should go to the myerror file" >&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 "This should display on the screen" echo "and this should be stored in the file" >&3 echo "And this should be back on the screen"
      
      





スクリプトの実行後、出力の一部は画面に、一部は記述子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



ます。 このコマンドは、システムで開いている各記述子に関する情報を表示するため、非常に便利です。 これには、バックグラウンドで実行されているプロセスが発見したもの、およびログインしているユーザーが開いているものが含まれます。



このコマンドには多くのキーがあります。最も重要なキーを検討してください。





現在のプロセスの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シグナル、スクリプトでそれらを処理する方法、スケジュールされたタスクの実行、およびバックグラウンドタスクについて説明します。



親愛なる読者! この資料は、入力、出力、およびエラーストリームの操作の基本を提供します。 私たちはあなたの中に、経験のみによってもたらされるすべてのことを話すことができる専門家がいると確信しています。 もしそうなら-あなたに言葉を渡します。






All Articles