シェルスクリプトでユーザー入力を受け付けたい

シェルスクリプトで対話的にユーザーからの入力を受け付けたい場合、readコマンドを使う。

readコマンドには-p-s-tといったオプションがあり、プロンプト表示・パスワード入力・タイムアウトをそれぞれ実現できる。

-p でプロンプトを表示する

-pオプションを使用すると、入力を促すプロンプトを表示できる。

#!/bin/bash
read -p "Enter your name: " name
echo "Hello, $name!"

実行すると、プロンプトを表示した上で入力値をname変数に代入する。

Enter your name: Alice
Hello, Alice!

-s でパスワードなど画面に表示したくない入力を受け付ける

-sオプションを使用すると、入力内容を画面表示せずに読み込める。パスワードなど、画面に表示したくない入力の受け付けに使う。

#!/bin/bash
read -s -p "Enter password: " password
echo
echo "Password length: ${#password}"

入力中は文字が表示されないため、パスワードの盗み見を防げる。

Enter password:
Password length: 9

-sは改行も表示しないため、入力後にechoだけを実行して改行を挟むとよい。

-t で入力待ちにタイムアウトを設定する

-tオプションを使用すると、指定した秒数以内に入力がなければタイムアウトさせられる。無人環境でスクリプトが入力待ちのまま止まってしまうのを防げる。

#!/bin/bash
if read -t 3 -p "Enter something (3s timeout): " something; then
  echo "You entered: $something"
else
  echo
  echo "Timed out!"
fi

時間内に入力があった場合はreadが正常終了し、$somethingに入力値が入る。

Enter something (3s timeout): hello
You entered: hello

時間内に入力がなかった場合はreadが失敗を返すため、if文のelse側に分岐する。

Enter something (3s timeout):
Timed out!

オプションの組み合わせ

-p-s-tは組み合わせて使用できる。たとえば、タイムアウト付きでパスワードを読み込む場合は以下のようになる。

read -s -t 10 -p "Enter password (10s timeout): " password