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 "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
ます。 このコマンドは、システムで開いている各記述子に関する情報を表示するため、非常に便利です。 これには、バックグラウンドで実行されているプロセスが発見したもの、およびログインしているユーザーが開いているものが含まれます。
このコマンドには多くのキーがあります。最も重要なキーを検討してください。
-
-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シグナル、スクリプトでそれらを処理する方法、スケジュールされたタスクの実行、およびバックグラウンドタスクについて説明します。
親愛なる読者! この資料は、入力、出力、およびエラーストリームの操作の基本を提供します。 私たちはあなたの中に、経験のみによってもたらされるすべてのことを話すことができる専門家がいると確信しています。 もしそうなら-あなたに言葉を渡します。