2016-02-15 89 views
0

我正在爲Linux終端編寫一個shell腳本。我希望能夠將變量輸入到提示中。例如Linux shell腳本:允許用戶在輸入中使用變量

test.sh:

test="Monkey in the middle..." 
read -p "Enter input: " input 
echo $input 

輸出:

Enter input: $test 
$test 

我希望能夠輸入 「$測試」(讀-p)提示段時的腳本,並且在末尾有腳本回聲「中間的猴子......」,而不是像現在這樣回顯「$ test」。

我該怎麼做呢?



UPDATE:(!非常感謝貢獻者和評論家)

使用提供給我在這裏和this thread答案,我設法拼湊出這行很努力以及對我來說:

newvariable="$(eval echo $input)" 

是的,建議,我被警告過一次,使用eval可能構成安全風險。記住,如果你選擇這個解決方案。

+1

如此疲憊的大腦不應該編程。我將刪除評論,但是當您使用'eval'時,問題會變得嚴重。既然你選擇了'eval'加命令替換,保護自己不受意外插入的影響應該成爲首要任務(並且會非常棘手 - 我不認爲我會確保我能夠正確地完成它)。謹防!你被警告過。用戶可能會是惡毒的,有時會是偶然的。 –

+0

@JonathanLeffler感謝您的警告。我正在shell中創建一個buckup腳本,我將最終與任何想要使用它的人分享。它們可以輸入到提示符中的變量將簡單地允許它們將20個字符長的字符串(例如日期/時間戳和PC /平臺的名稱)替換爲2-3個字符長的變量,以便它們不必在每次運行時鍵入它們劇本。除非用戶決定對自己的系統執行攻擊,否則對系統的風險是不存在的。 – thebunnyrules

+0

@JonathanLeffler你不是第一個警告我使用eval的人。據我自己的知識,使用它有哪些安全風險?我唯一能想到的是用戶可以輸入有害的代碼到提示中,但是爲了做到這一點,他們需要以sudo的方式運行腳本,如果他們已經可以做到這一點,他們可以直接在bash中運行代碼。有沒有其他的威脅可以構成我沒有想到的? – thebunnyrules

回答

1

這個問題有幾個不同的答案。

如果您在實際使用bash,看看在bash(1)手冊頁和閱讀參數擴展部分:

如果參數的第一個字符是一個感嘆號 (!),它引入了一個可變間接級別。 Bash使用 從其餘參數形成的變量的值爲 變量的名稱;這個變量然後被擴展,並且 該值用於其餘的替換,而不是 參數本身的值。這被稱爲間接 擴展。此例外是下面描述的 ${!prefix*}${!name[@]}的擴展。感嘆號 點必須立刻跟着左括號以 介紹間接。

這意味着,如果您有:

read $input 
echo "${!input}" 

且用戶輸入 「HOME」,你會看到的$HOME值。對於 例如,我的系統上:

Enter input: HOME 
/home/lars 

或者,你可以使用eval命令,它應該工作正常 任何的Bourne外殼般的環境:

EVAL [ARG ...]

參數被讀取並連接成一個命令。 然後該命令由shell讀取並執行,並且其退出 狀態作爲eval的值返回。如果沒有指定參數時,或僅 空參數,EVAL返回0

您的代碼可能是這樣的:

read $input 
eval echo "\$$input" 

外殼將首先擴大$input的價值,從而使 所得的命令行 - 假定有人進入HOME在 響應於該提示 - 是:

eval echo $HOME 

Ť他\$只是將$\一起轉義,以便在通過命令行傳遞第一個 期間,shell 不會將其解釋爲變量的開始。

但這裏有一個問題,請考慮:

Enter input: ;date 
$ 
Sun Feb 14 21:13:33 EST 2016 

在這個例子中,分號導致shell執行命令, 這不一定是我們所期望的或需要的。您可以 更好的報價有所緩解此:

eval echo \""$input"\" 

這在上面的例子中的結果:

$ sh foo.sh 
Enter input: ;date 
$;date 

但這裏的教訓是「不要在安全性敏感 情況下使用eval。」

+0

非常感謝您的幫助。我最終使用了在你的答案的第二部分中提出的eval:newvariable =「$(eval echo $ input)」。 – thebunnyrules