デフォルト値でbashの変数を読み取る


191

bashスクリプトでターミナルから値を読み取る必要があります。ユーザーが変更できるデフォルト値を提供できるようにしたいと思います。

# Please enter your name: Ricardo^

このスクリプトでは、プロンプトは「名前を入力してください:」です。デフォルト値は「Ricardo」で、カーソルはデフォルト値の後にあります。これをbashスクリプトで行う方法はありますか?

回答:


278

あなたが使用することができるパラメータ展開などを

read -p "Enter your name [Richard]: " name
name=${name:-Richard}
echo $name

大括弧の間のプロンプトにデフォルト値を含めることは、かなり一般的な慣習です


7
私はこれに基づいて何かをすることになりました。一時変数に読み込んinputでから使用しname=${input:-$name}ます。
Ricardo Marimon、2010

41
これは実際には質問の答えにはなりません。デフォルト値がプロンプトに表示されます。
パーソンパーソンII

3
そして何をname=${!input:-$name}しますか?
ハリーリー

8
{: - remote_host_default $ REMOTE_HOST}:-p読む"[$ remote_host_default]リモートホスト名を入力してください:" REMOTE_HOST REMOTE_HOST = $ - @ Dr.PersonPersonIIあなたはこのような何か実行して、デフォルト値を追加することができます
Dobler

4
$1になる${1:-some_default_string}
ThorSummoner

159
read -e -p "Enter Your Name:" -i "Ricardo" NAME

echo $NAME

1
正解です。「リカルド」とNAMEの間のスペースが見えなかったので、問題があったことをお伝えしたいと思いますが、それがわかったら、魔法です。ありがとうございました!
氏ミッケル

40
残念ながら、-i isはOSX 10.7の有効なオプションではありません
未定義

3
:あなたは自作使ってbashをアップグレードすることができます@BrianMortenson stackoverflow.com/questions/16416195/...
antonagestam

2
この回答は、OS X(Bash 3.x)でこれを機能させる方法を示しています。stackoverflow.com
クリストフPetschnig

3
実際に機能-eする-iためには必須であるように思われることに注意してください
MestreLion

48

バッシュ4では:

name="Ricardo"
read -e -i "$name" -p "Please enter your name: " input
name="${input:-$name}"

次のようにプロンプ​​トの後に名前が表示されます。

Please enter your name: Ricardo

名前の末尾にカーソルを置き、ユーザーが名前を編集できるようにします。最後の行はオプションであり、ユーザーが入力またはデフォルト(nullを送信)を消去すると、名前は強制的に元のデフォルトになります。


bash4はdebianディストリビューションでは非標準であるため、使用できません。手間をかけずに機能するものが必要です。
Ricardo Marimon、2010

1
コードの最後の行は必要ありません。コマンドのname代わりに使用inputしてくださいread
RNA

1
@RNAer:追加の変数を使用することにより$name、ユーザーが提案された値を削除した場合(したがってNULL文字列を入力した場合)の値が保持されます。それはすべてあなたのニーズが何であるかに依存します。私は私の答えで同じように言った。しかし、あなたがそうだと思いますが、私はより明示的である可能性があり、オプションの行が使用されない場合、変数はそうである可能性があると述べましたname
追って通知があるまで一時停止。

1
@DennisWilliamson:その通りです。それが望まれるのであれば、それは良い習慣です。
RNA

16

コード:

IN_PATH_DEFAULT="/tmp/input.txt"
read -p "Please enter IN_PATH [$IN_PATH_DEFAULT]: " IN_PATH
IN_PATH="${IN_PATH:-$IN_PATH_DEFAULT}"

OUT_PATH_DEFAULT="/tmp/output.txt"
read -p "Please enter OUT_PATH [$OUT_PATH_DEFAULT]: " OUT_PATH
OUT_PATH="${OUT_PATH:-$OUT_PATH_DEFAULT}"

echo "Input: $IN_PATH Output: $OUT_PATH"

サンプルの実行:

Please enter IN_PATH [/tmp/input.txt]: 
Please enter OUT_PATH [/tmp/output.txt]: ~/out.txt
Input: /tmp/input.txt Output: ~/out.txt

これは、デフォルト値がコロンの前の角括弧内にある多くのシェルスクリプトで見られる慣例に従っているため、これが好きです。ありがとう!!!
モーフィック2017

16

私は次のようなものを提示する方法を探して、この質問を見つけました:

Something interesting happened.  Proceed [Y/n/q]:

上記の例を使用して、私はこれを推定しました:-

echo -n "Something interesting happened.  "
DEFAULT="y"
read -e -p "Proceed [Y/n/q]:" PROCEED
# adopt the default, if 'enter' given
PROCEED="${PROCEED:-${DEFAULT}}"
# change to lower case to simplify following if
PROCEED="${PROCEED,,}"
# condition for specific letter
if [ "${PROCEED}" == "q" ] ; then
  echo "Quitting"
  exit
# condition for non specific letter (ie anything other than q/y)
# if you want to have the active 'y' code in the last section
elif [ "${PROCEED}" != "y" ] ; then
  echo "Not Proceeding"
else
  echo "Proceeding"
  # do proceeding code in here
fi

同じ問題が発生した場合に、ロジックを考える必要がない人を助けることを願っています


非常に素晴らしい。誰かが「k」または指定された選択肢以外の何かを入力した場合、質問を繰り返すことで少し改善することもできます。
erikbwork 2017

1
このコメントは、かゆみを伴うかゆみに続いて書きました。これで、上記を含むシェル関数ができました。それを使用する傾向があります。シェルはうまくループしていないようなので、私はそれを避けようとします。関数の結果をテストしてもう一度試してみるかもしれませんが、基本的には、問題が発生する可能性がある場所で管理ツールを作成しているため、管理者がいつでもスクリプトをきれいに停止できるようにしたいと考えています。
sibaz


6
name=Ricardo
echo "Please enter your name: $name \c"
read newname
[ -n "$newname" ] && name=$newname

デフォルトを設定します。それを印刷します。新しい値を読み取ります。新しい値がある場合は、デフォルトの代わりに使用してください。プロンプトの最後で改行を抑制する方法について、シェルとシステムの間にはいくつかのバリエーションがあります(またはありました)。「\ c」表記は、3.x bashを使用するMacOS X 10.6.3で機能するようであり、BourneまたはKornシェルを使用して、System Vから派生したUnixのほとんどのバリアントで機能します。

また、ユーザーは舞台裏で何が行われているのかおそらく理解できないことに注意してください。それらの新しいデータは、すでに画面上にある名前の後に入力されます。それをフォーマットする方が良いかもしれません:

echo "Please enter your name ($name): \c"

printfよりも移植性が高いecho
ghostdog74 2010

3
@ ghostdog74:多分そうです。25年以上前にシェルプログラミングを学んだ私たちの人々は、私たちの実践のどれがまだ関連性があるかを考えるのに苦労しています。それはますますbashがすべてについて書き直したように見えます。私はprintfがコマンドとしてしばらく前から存在していることを知っています-しかし、ほとんど使用しません(おそらく-一度も使用しませんか?)。私はbashを(再)習得するまで、シェルをシャットダウンする必要があるという印象を受けます。おかしいです。私が取り組んでいるソフトウェアには、うまく動作しないシェルスクリプトがありますが、問題はbash-ismsではありません。' if (test -z "$xxx"); ...'やその他のCシェルの修正にうんざりしています。
ジョナサンレフラー2010

bash \cもサポートしていることに驚いていますecho -n。ただし、-eエスケープを解釈するには、bashのエコーを取得するために追加する必要があります。私\cは言っていないもののためだと思います:echo -e "Syntax slightly off\c, but I've learned so much from what you've shared. Thanks, @JonathanLeffler!"
jpaugh

1
#Script for calculating various values in MB
echo "Please enter some input: "
read input_variable
echo $input_variable | awk '{ foo = $1 / 1024 / 1024 ; print foo "MB" }'

3
回答に説明を追加してください。
Sufiyan Ghori 2015年

-1

-eパラメーターと-tパラメーターは一緒には機能しません。私はいくつかの式を試しましたが、結果は次のコードスニペットでした:

QMESSAGE="SHOULD I DO YES OR NO"
YMESSAGE="I DO"
NMESSAGE="I DO NOT"
FMESSAGE="PLEASE ENTER Y or N"
COUNTDOWN=2
DEFAULTVALUE=n
#----------------------------------------------------------------#
function REQUEST ()
{
read -n1 -t$COUNTDOWN -p "$QMESSAGE ? Y/N " INPUT
    INPUT=${INPUT:-$DEFAULTVALUE}
    if  [ "$INPUT" = "y" -o "$INPUT" = "Y" ] ;then
        echo -e "\n$YMESSAGE\n"
        #COMMANDEXECUTION
    elif    [ "$INPUT" = "n" -o "$INPUT" = "N" ] ;then
        echo -e "\n$NMESSAGE\n"
        #COMMANDEXECUTION
    else
        echo -e "\n$FMESSAGE\n"
    REQUEST
    fi
}
REQUEST

あなたの答えは質問とはあまり関係ありませんね…
gniourf_gniourf 2014年

-eおよび-tパラメーターを使用するための回避策です。このコードライン(デフォルト値は-eおよび-i):read -e -p "Enter Your Name:" -i "Ricardo" NAMEはカウントダウン
タイマー

ええ、でもそれは質問では尋ねられませんね?
gniourf_gniourf 2014年

3
あなたができることは、新しい質問をして、自分で答えること;)です。これはSOで許可されています!しかし、私たちは無関係なもので他の質問を汚したくありません。
gniourf_gniourf 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.