2010-04-15 110 views
109

我需要在bash腳本中從終端讀取一個值。我希望能夠提供用戶可以更改的默認值。在bash中讀取一個默認值的變量

# Please enter your name: Ricardo^ 

在此腳本中,提示是「請輸入您的姓名:」默認值爲「Ricardo」,光標位於默認值之後。有沒有辦法在bash腳本中做到這一點?

回答

142

可以使用parameter expansion

read -p "Enter: " name 
name=${name:-Richard} 
echo $name 
+4

我最終做了一些基於此。讀入一個臨時變量'input',然後使用'name = $ {input: - $ name}'。 – rmarimon 2010-04-15 05:05:15

+26

這實際上並沒有回答這個問題。應在提示中顯示默認值。 – 2011-10-26 00:47:21

+0

和'name = $ {!input: - $ name}'會做什麼? – 2015-03-17 10:27:49

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

設置默認值;打印它;讀一個新的價值;如果有新值,則用它代替默認值。在shell和系統之間存在(或者是)一些關於如何在提示結束時禁止換行符的變體。 '\ c'符號似乎可以在MacOS X 10.6.3上使用3.x bash,並且適用於從System V派生的大多數Unix變體,使用Bourne或Korn shell。

另請注意,用戶可能不會意識到幕後發生了什麼;他們的新數據將在屏幕上的名稱後輸入。這可能是更好的對其進行格式化:

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

'printf'比'更便攜echo' – ghostdog74 2010-04-15 03:54:50

+1

@ ghostdog74:也許是這樣;我們這些在25年前學習shell編程的人很難確定我們的哪些做法仍然相關。它越來越像bash改寫了一切。我知道printf作爲命令已經有一段時間了 - 我很少使用它,儘管(可能 - 從來沒有?)。我得到的印象我應該閉嘴殼直到我(重新)學習bash。 「這很有趣;我工作的軟件有一些不太好的shell腳本 - 但麻煩不是bash-isms。我只是厭倦了修復'if(test -z「$ xxx」); ......「和其他C shellism。 – 2010-04-15 07:20:40

33

在bash 4:

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

這這樣的提示後,顯示的名稱:

Please enter your name: Ricardo 

與遊標在名稱的末尾,並允許用戶編輯它。最後一行是可選的,如果用戶刪除了輸入或默認值(提交null),強制名稱爲原始默認值。

+0

不能使用bash4,因爲它在debian發行版中是非標準的。我需要一些能夠毫無麻煩地工作的東西。 – rmarimon 2010-04-15 05:06:26

+0

不需要最後一行代碼,只需在'read'命令中使用'name'而不是'input'即可。 – RNA 2012-03-15 23:59:14

+1

@RNAer:通過使用額外變量,如果用戶刪除建議值(並因此輸入空字符串),則會保留'$ name'的值。這完全取決於你的需求。我在答覆中說了很多。不過,你說得對,我可以更加明確地說,如果可選行沒有被使用,那麼這個變量可能是'name'。 – 2012-03-16 11:43:58

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

echo $NAME 
+1

很好的答案!我只想提一提,我遇到了麻煩,因爲我沒有看到「裏卡多」和NAME之間的空間,但是一旦我發現了...... *魔法*!謝謝! – 2012-06-17 00:05:05

+25

不幸的是,我不是OSX的有效選項10.7 – undefined 2013-01-22 17:37:32

+0

@BrianMortenson您可以使用自制軟件升級bash:http://stackoverflow.com/questions/16416195/how-do-i-upgrade-bash-in-mac-osx -mountain-lion-and-set-it-the-correct-path – antonagestam 2014-04-01 22:13:04

10

代碼:

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 
+0

我喜歡這個,因爲它遵循我在很多shell腳本中看到的約定,默認值在冒號前的方括號中。謝謝!!! – morphatic 2017-08-04 18:35:23

-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 
+0

你的答案與這個問題沒有太大關係,是嗎?... – 2014-11-08 20:16:49

+0

它的工作是使用-e和-t參數。 此代碼行(-e和-i默認值): 讀-e -p 「輸入你的名字:」 -i 「裏卡多」 NAME 不以countdowntimer(-t)工作 – speefak 2014-11-08 20:31:35

+0

呀但這是在問題中沒有問,是嗎? – 2014-11-08 20:36:13

0
#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

請將解釋添加到您的答案。 – 2015-01-13 12:44:10

9

我發現這個問題,尋找一種方式來呈現類似:

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 

希望幫助別人不必想出邏輯,如果他們遇到同樣的問題

+0

非常好。如果某人只輸入「k」或其他與給定選擇不同的東西,甚至可以稍微改進一點。 – erikbwork 2017-04-10 12:03:24

+1

我剛剛寫下這個評論後,抓撓了癢。我現在有一個shell函數,其中包括上述,我傾向於使用它。殼似乎沒有很好地循環,所以我儘量避免它。我可能會測試我的函數的結果,並給出一個更多的嘗試,但基本上,我正在編寫管理工具,可能出現問題,所以我希望管理員能夠在任何時候乾淨地停止腳本。 – sibaz 2017-04-11 10:06:55

6

我只是用這個模式,這是我比較喜歡:

read name || name='(nobody)'