read - 標準入力から変数に代入する

スポンサーリンク

readコマンドはユーザからの入力を変数に代入することができます。

また、オプションによって、「>」のような文字を入力する前の文字列として追加し、ユーザに文字入力の要求を分かりやすくすることができます。

スポンサーリンク

readコマンドの利用例

変数に代入
(オプションなし)

readコマンドは引数に変数名を取ります。その後、標準入力から行を読み取ります。コマンド例の2行目、つまり、readコマンドの後の行は端末からの入力した行になります。入力した行はreadコマンドで引数にした変数に代入されます。

コマンド例と実行結果

 

readコマンドで引数に複数の変数を指定した場合は、入力した行は単語毎に区切られ、変数に代入されます。また、区切り文字は環境変数IFSで決められます。

そして、入力した行の単語が変数より多い場合は、引数で指定した最後の変数に残りの行がすべて代入されます。

コマンド例と実行結果

 

readコマンドで変数が何も指定されない場合は、入力した行は変数REPLYに代入されます。

コマンド例と実行結果

 

 

 

配列変数に代入
(-aオプション)

-aオプションの後に変数を指定した場合は、その変数を配列変数として扱い、入力した行を単語ごとに区切って、その配列変数に代入していきます。配列変数は0から順に代入されていきます。

また、-aオプションを用いた場合、readコマンドで指定する他の変数は無視されます。

コマンド例と実行結果

 

 

 

入力を終了する文字を指定
(-dオプション)

-dオプションを用いると、入力を終了する文字を改行ではなく、別の文字にすることができます。また、入力を終了する文字は、-dオプションで指定した最初の文字が設定されます。

例えば、コマンド例では「;」を入力を終了する文字として指定しています。そして、readコマンドの入力が始まり、「;」を入力した時点でreadコマンドの入力が終了して、「$」という端末の文字が表示されています。

コマンド例と実行結果

 

 

 

入力でコマンドライン補完などの機能を使用
(-eオプション)

-eオプションを用いるとreadコマンドの入力時にコマンドラインでの補完のような機能が使用できるようになります。

例えば、カレントディレクトリに

のように「file.txt」があるときに

のように、「fi」を入力し、ここでTABを入力すると

「file.txt」として入力を補完することができます。

 

 

 

Readline使用時に文字列を事前に入力バッファに
(-iオプション)

-iオプションは、-eオプションと組み合わせて使用します。

-iオプションを用いると、-iオプションの引数にある文字列をreadの入力バッファに事前に書き込んだ状態でreadコマンドの入力を始めることができます。

コマンド例と実行結果

 

 

 

入力文字数を制限
(-nオプション)

-nオプションを用いると、指定した文字数が入力された時点で入力が終了するようになります。

コマンド例と実行結果

 

 

 

指定した文字を読み込む
(-Nオプション)

EOFとタイムアウト以外は指定した文字数を読み込むまで入力を終了しません。

コマンド例と実行結果

 

 

 

端末から入力するときに文字列を表示
(-pオプション)

-pオプションは、readコマンドで端末から入力するときに、入力する前に表示するプロンプトの文字を設定することができます。

コマンド例と実行結果

 

 

 

エスケープ文字を無効
(-rオプション)

-rオプションを用いると、バックスラッシュをエスケープ文字として扱いません。また、readコマンドの次の行は文字を入力しています。

コマンド例と実行結果

 

 

 

サイレントモード
(-sオプション)

-sオプションを用いると、入力時にその入力文字を表示しません。コマンド例では、readコマンドを実行した後に、readコマンドの入力モードに移り、「silent mode」と入力しています。

コマンド例と実行結果

 

 

 

入力の時間制限
(-tオプション)

-tオプションを用いると、入力時間を指定することができます。また、時間は秒数で指定します。

コマンド例

 

 

 

ファイルディスクリプタを指定して入力
(-uオプション)

リダイレクトをするときに基本的に省略されますが、>や<の前に数字を入れる場合、その数字はファイルディスクリプタ(file descriptor, fd)を表します。一般的によく使用されるファイルディスクリプタは、0が標準入力、1が標準出力、2が標準エラー出力を表します。

-uオプションを用いるとファイルディスクリプタを指定して、入力を読み込むことができます。コマンド例では、5という数字のファイルディスクリプタに「file.txt」を設定しています。

file.txt

コマンド例と実行結果

 

また、execコマンドを用いてファイルディスクリプタを設定することもできます。
exec 5<file.txtでファイルを読み込み専用で指定したファイルディスクリプタにオープンし、
exec 5<&-で指定したファイルディスクリプタをクローズします。

コマンド例

 

 

 

パイプとreadコマンド

パイプを用いて、readコマンドを使用するとき、注意が必要です。例えば、パイプを用いて、readコマンドを呼び出すと意図した動作と違う動作に思えるかもしれません。

 

これは、パイプで実行するコマンドが呼び出された実行環境を引き継いだサブシェル環境という別の実行環境で処理されるためです。このサブシェル環境は呼び出された親の実行環境に影響を及びません。

上のコマンドで変数を確認する場合は、パイプから丸括弧でreadコマンドとechoコマンドを囲むと代入された変数を確認することができます。

 

また、declareコマンドを用いると実効環境の変化を見ることができます。

下のコマンドでは事前に変数varに対してを入れた状態で、始めに変数varに対しての値を確認しています。次にreadコマンドで変数に値を入れたときの変数varの値を確認し、最後にreadコマンドを実行した後で、もう一度確認しています。

 

このことから、サブシェル環境が現在のシェル環境での変数に影響を及ぼしていないことが確認できます。

 

 

 

whileと組み合わせてファイルから行を読み込む

whileのような複合コマンド(Compound Commands)へのリダイレクトは明示的に上書きをしない限り、複合コマンドで用いるすべてのコマンドに適用されます。

while文でreadコマンドでファイルから行を読み込む場合、while文の後にリダイレクトを行います。

file.txt

コマンド例と実行結果

複合コマンドとは、while,until,forのようなループ、if,case,selectのような条件分岐、()や{}のようなコマンドのグループ化があります。

 

 

 

参考

GNU Bash manual