何が読まれますか?
Readは、行の内容を変数に読み込むbash組み込みコマンドです。これにより、特別なシェル変数IFSに関連付けられた単語分割が可能になります。これは主にユーザー入力をキャッチするために使用されますが、標準入力から入力を取得する関数を実装するために使用できます。
Bash読み取り組み込みコマンドヘルプ
bashスクリプトでreadコマンドを使用する方法に飛び込む前に、ここでヘルプを取得する方法を説明します。そこには、readコマンドで使用できるすべてのオプションと、例で取り上げる説明が表示されます。
コマンドライン
ヘルプ 読んだ
出力
読んだ:読んだ [-ers] [-配列] [-dシェア] [-iテキスト] [-n nchars] [-N nchars]
[-pプロンプト] [-tタイムアウト] [-u fd] [名前 ...]
標準入力から行を読み取り、スプリットそれをフィールドに入れます。
標準入力またはから1行を読み取りますファイル記述子FD
もしもNS-uオプションが提供されます。ラインはスプリットフィールドになので言葉で
分割すると、最初の単語が最初のNAMEに割り当てられ、2番目の単語が割り当てられます
2番目のNAMEへの単語など、残りの単語はに割り当てられます
NS過去名前。見つかった文字のみの $ IFS認識されますなので言葉
区切り文字。
NAMEが指定されていない場合、次の行読んだ保存されていますのREPLY変数。
オプション:
-に配列は単語を割り当てます読んだ配列のシーケンシャルインデックスへ
ゼロから始まる変数ARRAY
-NSデリム継続する それまでDELIMの最初の文字は読んだ、 それよりも
改行より
-eReadlineを使用して行を取得しますのインタラクティブシェル
-私テキストはTEXTを使用しますなので最初のテキストにとって読み込まれた行
-NSnchars戻る待つのではなくNCHARS文字を読んだ後
にとって改行ですが、区切り文字を尊重しますもしもより少ない
NCHARS文字は読んだ区切り文字の前
-NSnchars戻るNCHARS文字を正確に読み取った後でのみ、
EOFが発生した、または読んだ タイムズアウト、無視して
デリミタ
-NSプロンプトは、前に改行なしで文字列PROMPTを出力します
試行する読んだ
-NSNSバックスラッシュで文字をエスケープしないでください
-NSNSいいえ捨てた端末からの入力
-NSタイムアウト時間アウトと戻る失敗もしもに完了のライン
入力はありません読んだタイムアウト秒以内。の値
TMOUT変数はデフォルトのタイムアウトです。タイムアウトは
分数。タイムアウトが0、読んだ戻り値
すぐに、しようとせずに読んだ任意のデータ、
成功のみもしも指定された上で入力が可能です
ファイルディスクリプタ。 NS出口ステータスがより大きい128
もしもタイムアウトを超えています
-ufd読んだからファイル標準入力の代わりに記述子FD
終了ステータス:
NS戻るファイルの終わりに遭遇しない限り、コードはゼロです。読んだ タイムズアウト
((の どれの 場合それが128より大きい)、変数の割り当てエラー
ユーザー入力をキャッチする
インタラクティブなbashスクリプトは、ユーザー入力をキャッチすることなしには何もありません。組み込みの読み取りは、ユーザー入力をbashスクリプト内でキャッチできるメソッドを提供します。
入力行をキャッチする
入力の行をキャッチするために、NAMEとオプションは読み取りでは必要ありません。 NAMEが指定されていない場合、ユーザー入力を格納するためにREPLYという名前の変数が使用されます。
コマンド
{{捨てた -NS '何かを入力してEnterキーを押します:';
読んだ;
捨てた入力しました$ {返信}
}
出力
何かを入力してEnterキーを押します:何か((改行)。あなたは何かをタイプしました
入力の単語をキャッチ
入力の単語をキャッチするには、-dオプションが必要です。単語の場合、-dをスペースに設定し、「-d」と読みます。つまり、ユーザーがスペースバーを押すと、読み取られた単語がREPLYに読み込まれます。
-dオプションを設定すると、バックスペースが期待どおりに機能しないことに注意してください。バックスペースするには、入力の単語をキャッチしようとしているときに、-eオプションを使用できます。-e‘-d ‘を読んでください。
コマンド
捨てた -NS '何かを入力してスペースを押す:';
読んだ '-NS ';
捨てた '';
捨てた 'あなたはタイプしました$ {返信}'
}
出力
何かを入力してスペースを押す:何か((スペース)。あなたは何かをタイプしました
プロンプトユーザー
インタラクティブなbashスクリプトでは、ユーザーにプロンプトを表示するために、どの入力が期待されるかをユーザーに伝えるメッセージが必要になる場合があります。組み込みのechoを使用して、これをいつでも実現できます。ただし、読み取りを使用するオプションがあることがわかりました。
ユーザーに単語を促す
入力の単語をキャッチする際に、echoを使用してTypesomethingを書き込み、スペースをヒットしました。「-d」を読み取る前に標準出力に書き込みます。 -pオプションを使用すると、標準入力から読み取る前にメッセージを表示できます。
コマンド
{{読んだ -NS '何かを入力してスペースを押す:' '-NS ';
捨てた '';
捨てた 'あなたはタイプしました$ {返信}'
}
出力
何かを入力してスペースを押す:何か((スペース)。あなたは何かをタイプしました
ユーザーに秘密を求める
端末に表示されずにユーザー入力をキャッチする場合は、-sオプションが便利です。 read -s -pを使用すると、次のようにユーザー入力をキャッチおよび非表示にできます。
コマンド
{{読んだ -NS -NS 「秘密にしておくと約束したものを入力してください:」
捨てた '';
捨てた 「あなたの秘密は私にとって安全です」;未設定返事 ;
捨てた '$ {返信}'
}
出力
秘密にしておくと約束したものを入力してください。あなたの秘密は私と一緒に安全です
読み取りを使用する関数
読み取りと標準入力を使用するbashの関数の例を次に示します。
核心概念
読み取りを使用する関数は、パイプされた標準入力とパラメーターを利用します。ファイル内の行など、処理されるメイン入力は、パイプを介して標準入力を介して渡されます。その他の入力if-anyおよびoptionはパラメーターとして渡されます。
読んだ -NS 1NAME1 NAME2..。読んだはビルトイン 指図
-t 1は、bashスクリプトが標準入力を介して行が返されるのを無期限に待機するのを防ぎます。標準入力が最初は空の場合、関数は終了コード142で戻り、設定されたタイムアウト期間内に日付が読み取られなかったことを示します。
NAME1NAME2は変数名です...多くの変数名がリストされる場合があります
基礎が整ったので、readを使用して実装されたおなじみの関数がどのように見えるかを見てみましょう。
読み取りを使用した結合関数
単語のリストを受け取り、区切り文字で結合された単語の別のリストを返す結合関数が必要だとします。読み取りを使用して結合関数を実装する方法は次のとおりです。
脚本#!/ bin / bash
## 加入
##バージョン0.0.2-再帰パラメータを修正
##################################################
加入(()。 {{ {{ ローカルリミッタ;リミッタ='$ {1-}';ローカルアウトデリミタ;
アウトデリミタ='$ {2-。}';}
ローカル車両
ローカルcdr
ローカルIFS
IFS='$ {indelimiter}'
読んだ -NS 1車のcdr|| 戻る
テスト '$ {cdr}' || {{ 捨てた '$ {car}';戻る;}
捨てた '$ {car}$ {outdelimiter}$ {cdr}' | $ {FUNCNAME} '$ {indelimiter}'
'$ {outdelimiter}'
}
##################################################
## create-stub2.shv0.1.2によって生成されます
## 2019年6月17日月曜日12:24:59 + 0900
## 見る
##################################################
ソース: join.sh
コマンドライン
出力
a.bコマンドライン
捨てたa b| 加入 | 加入。 |出力
に|NS読み取りを使用して関数をマップします
リストを受け取り、別の関数によって変更された同じ数の要素を含む別のリストを返すマップ関数が必要だとします。 readを使用してmap関数を実装する方法は次のとおりです。
脚本#!/ bin / bash
##マップ
##バージョン0.0.1-初期
##################################################
地図(()。 {{ {{ ローカルfunction_name;function_name='$ {1}';}
ローカル車両
ローカルcdr
ローカルIFS
IFS='$ {indelimiter-}'
読んだ -NS 1車のcdr|| 戻る
テスト '$(declare -f $ {function_name})' || 戻る
テスト '$ {car}' || {{ NS;戻る;}
$ {function_name} $ {car}
捨てた '$ {cdr}' | $ {FUNCNAME} '$ {function_name}'
}
##################################################
## create-stub2.shv0.1.2によって生成されます
## 2019年6月18日火曜日08:33:49 + 0900
## 見る
##################################################
ソース: map.sh
コマンド
捨てた {{1..10} |マップパウ
出力
14
9
16
25
36
49
64
81
100
読み取りを使用したフィルター機能
リストを受け取り、別の関数によって設定された条件を満たす要素のサブリストを返すフィルター関数が必要だとします。これが、readを使用してフィルター関数を実装する方法です。
脚本#!/ bin / bash
## フィルター
##バージョン0.0.1-初期
##################################################
フィルター(()。 {{ {{ ローカルfunction_name;function_name='$ {1}';}
ローカル車両
ローカルcdr
ローカルIFS
IFS='$ {indelimiter-}'
読んだ -NS 1車のcdr|| 戻る
テスト '$(declare -f $ {function_name})' || 戻る
テスト '$ {car}' || {{ NS;戻る;}
$ {function_name} '$ {car}' || 捨てた -NS '$ {car}'
捨てた '$ {cdr}' | $ {FUNCNAME} '$ {function_name}'
}
##################################################
## create-stub2.shv0.1.2によって生成されます
## 2019年6月18日火曜日13:19:54 + 0900
## 見る
##################################################
ソース: filter.sh
コマンド
奇数(()。 {{ ローカル -私 私=$ {1};テスト !$((((私% 2 )。)。 -eq 1;}捨てた {{1..10} |奇数フィルター
出力
1 3 5 7 9読み取りを使用してループする
読み取りを使用するループを使用すると、生成されるファイルまたはすでに存在するファイルの行を反復処理できます。
左側の基本的なwhile読み取りループ(lhs)
readループとwhileループを使用してループできるファイル内の行を生成できるコマンドまたは関数(lhs)があります。
構築するlhs| その間 読んだ
NS
NS
終わり
lhsは指図行のリストを返します
コマンド
seq 5 | その間 読んだ私NS
捨てた $ {i}
終わり
出力
12
3
4
5
右側の基本的なwhile読み取りループ(rhs)
readループとwhileループを使用してループできる行を含むファイル(rhs)があります。
構築するその間 読んだ
NS
NS
終わり <rhs
rhsはファイル行を含む
コマンド
seq 5 >>rhsその間 読んだ私
NS
捨てた $ {i}
終わり <rhs
出力
1
2
3
4
5
読み取りを使用したカスタムlhswhileループ
readを使用してループしたい単語のストリームがあります。
構築する((
IFS=''
lhs| その間 読んだ
NS
NS
終わり
)。
lhsは単語のリストです
コマンド
((IFS=''
捨てた {{1..5} | その間 読んだ私
NS
捨てた '$ {i}
終わり
)。
出力
1 2 3 4 5標準入力の代わりに任意のfdから読み取る
多くの場合、変更されないままになっている組み込みの読み取りオプションは、どのファイル記述子から読み取るかを指定できるオプションです。read-uFDです。デフォルトでは、FDが標準入力と見なされます。
核心概念
ファイルを開いたときにファイル記述子が割り当てられます。 bashでのIOリダイレクトにより、特定のファイル記述子を使用してファイルを開いたままにすることができます。ファイルへの書き込み、ファイルからの読み取り、および完了したらファイルを閉じることができます。
_(()。{{
猫 /開発者/ヌル>>myfifo;#空のmyfifo
exec 3<myfifo;#ファイルmyfifoをfd3として開く
捨てた 'こんにちは世界! -fd 3 'から >>myfifo;#myfifoに書き込む
読んだ -u 3;#fd3から行を読み取る
exec 3>&-;#fd3を閉じる
捨てた $ {返信} #閉じる前にfd3から読み取った出力行
}
_# こんにちは世界! fd3から
ファイル記述子を使用してトレインを構築し、-uFDを読み取ります
楽しみのために、ファイル記述子を使用してトレインを作成し、-uFDを読み取ることにしました。各ファイル記述子には、番号が書き込まれます。各ファイル記述子は、以下のファイル記述子1から読み取り、それ自体に追加します。
コマンドライン
bashlinuxhint.com/建てる/test-read-fd.shトレイン10出力
fdsの初期化..。fdの初期化3..。
fd3初期化
fdの初期化4..。
fd4初期化
fdsが初期化されました
fdからの読み取り3と4..。
4 3
クリーンアップする前のfds
0 1 2 3 4 5
清掃 ...
fdsのクリーンアップ..。
終わりfdsのクリーンアップ
クリーンアップ後のfds
0 1 2 3
read -uFDを使用して機能をスキップする
実行している場合
うなめ -にMINGW64_NT-10.0デスクトップ-XVVVVVV2.7.0((0.307/5/3)。
2017年。-02-17 14:20x86_64 Msys
bash - バージョン
GNUbash、バージョン4.4.12((1)。-リリース((x86_64-pc-msys)。
バグが原因で、スクリプトソースが読み取られる前に、関数の外部でbashスクリプトの次の行をスキップするスキップ関数を実装できる可能性があります。ほとんどのシステムでは機能しないことに注意してください。例えば、
うなめ -にLinux 4.9.0-8-amd64#1 Debian SMP 4.9.144-3.1(2019-02-19)x86_64 GNU / Linux
bash - バージョン
GNUbash、バージョン4.4.12((1)。-リリース((x86_64-pc-linux-gnu)。
スキップは飛ばない。
関数
スキップ(()。 {{ 読んだ -u 31;}
コマンド
スキップ捨てた行がスキップされました
NS
出力
((空の)。結論
組み込みのbashの読み取りは、ユーザー入力をキャッチするだけではありません。これは、bashスクリプトで使用されるファイル記述子間の関数、ループ、および交換で使用できます。場合によっては、読み取り記述子とファイル記述子を使用して探索すると、イースターエッグが生成されることがあります。