read
| 対応: | 全Linux | |
|---|---|---|
| macOS(2001 Cheetah) | ||
| Bash 1.0(1989) |
『read』は標準入力(キーボード入力)や行データを変数に読み込む組み込みコマンドです。ユーザーへの対話的な入力プロンプト表示や、テキストファイルの行単位処理に使います。
構文
標準入力を変数に読み込みます。
read 変数名
『-p』オプションを付けるとプロンプトを表示して入力を受け付けます。
read -p "入力してください: " 変数名
『-s』オプションを付けると入力を非表示にします(パスワード入力向け)。
read -s -p "パスワード: " 変数名
『-a』オプションを付けると配列として読み込みます。
read -a 配列名
while ループでファイルを1行ずつ処理します。
while read line; do
echo "$line"
done < ファイル名
オプション一覧
| オプション | 概要 |
|---|---|
| -p "プロンプト" | 入力前にプロンプト文字列を表示します。 |
| -s | 入力を画面に表示しないサイレントモードです(パスワード入力向け)。 |
| -r | バックスラッシュをエスケープとして解釈しません(ファイル読み込みで推奨)。 |
| -a 配列名 | スペース区切りの入力を配列として読み込みます。 |
| -n 文字数 | 指定文字数を読み込んだら自動的に終了します。 |
| -t タイムアウト | 指定秒数で入力待ちをタイムアウトします。 |
| -d 区切り文字 | 改行の代わりに指定文字を入力の終端とします。 |
| -u ファイル記述子 | 指定したファイル記述子から読み込みます。 |
サンプルコード
『-p』オプションでプロンプトを表示して入力を受け付けます。
sample_read_name.sh
read -p "名前を入力してください: " name
echo "こんにちは、${name} さん!"
実行するコマンドは次の通りです。
bash read_name.sh 名前を入力してください: 八神庵 こんにちは、八神庵 さん!
『-s』オプションで入力を非表示にします。パスワード入力に使います。
sample_read_password.sh
read -s -p "パスワード: " password
echo ""
echo "パスワードを受け付けました(文字数: ${#password})"
実行するコマンドは次の通りです。
bash read_password.sh パスワード: パスワードを受け付けました(文字数: 8)
『-t』オプションでタイムアウトを設定します。指定秒数以内に入力がないと終了ステータス 1 を返します。
sample_read_timeout.sh
read -t 10 -p "続行しますか? [y/N]: " answer
if [ $? -ne 0 ]; then
echo "タイムアウト。処理を中断します。"
exit 1
fi
[ "$answer" = "y" ] || { echo "中断しました。"; exit 0; }
実行するコマンドは次の通りです。
bash read_timeout.sh 続行しますか? [y/N]: y
『-a』オプションでスペース区切りの入力を配列として受け取ります。
sample_read_array.sh
read -p "メンバーを入力(スペース区切り): " -a members
echo "1番目: ${members[0]}"
echo "すべて: ${members[@]}"
実行するコマンドは次の通りです。
bash read_array.sh メンバーを入力(スペース区切り): Iori Kyo Terry 1番目: Iori すべて: Iori Kyo Terry
ファイルを1行ずつ読み込んで処理します。『IFS=』で先頭・末尾の空白を保持し、『-r』でバックスラッシュのエスケープ解釈を防ぎます。
sample_read_file.sh
while IFS= read -r line; do
echo "行: $line"
done < /etc/hosts
実行するコマンドは次の通りです。
bash read_file.sh 行: 127.0.0.1 localhost 行: ::1 localhost
パイプからの入力も同様に処理できます。
sample_read_pipe.sh
ls /var/log/*.log | while read -r logfile; do
size=$(wc -l < "$logfile")
echo "$logfile: ${size}行"
done
実行するコマンドは次の通りです。
bash read_pipe.sh /var/log/syslog.log: 1520行 /var/log/auth.log: 340行
概要
ファイルを1行ずつ読み込む場合は『while IFS= read -r line』が定番です。『IFS=』で先頭・末尾の空白を保持し、『-r』でバックスラッシュのエスケープ解釈を防ぎます。
『-t』オプションでタイムアウトを設定すると、操作なしでスクリプトが止まらないようにできます。『-s』と『-p』を組み合わせたパスワード入力パターンはインストーラースクリプトでよく使われます。ループの詳細は while / until も参照してください。
よくあるミス
よくあるミス1: -r を付けないとバックスラッシュが展開される
-r なしの read は入力中のバックスラッシュをエスケープ文字として解釈します。『\n』などが意図せず変換されます。
echo "path: C:\\Users\\Iori" | read -r line echo "$line" path: C:\Users\Iori
ファイルやパイプからの読み込みには常に -r を付けます。
echo "path: C:\\Users\\Iori" | while IFS= read -r line; do echo "$line"; done path: C:\\Users\\Iori
よくあるミス2: IFS= を付けないと行頭・行末の空白が削除される
IFS を設定せずに read を使うと、読み込む行の先頭・末尾のスペースやタブが削除されます。
echo " 八神庵" | while read line; do echo "[$line]"; done [八神庵]
IFS= を設定すると空白が保持されます。
echo " 八神庵" | while IFS= read -r line; do echo "[$line]"; done [ 八神庵]
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。