2015-04-20 27 views
0

我有以下代碼:提示在bash腳本不顯示參數

#!/bin/sh 

g_yes=0 
g_no=-1 
g_cancel=1 
g_none=127 

show_yes_no_prompt() 
{ 
     rc=$g_none 
     prompt=$* 
     while true; do 
       read -p $prompt"(ync): " 
       case $yn in 
         [Yy]*) rc=$g_yes; break;; 
         [Nn]*) rc=$g_no; break;; 
         [Cc]*) rc=$g_cancel; break;; 
         *) echo "Please answer yes/no/cancel.";; 
       esac 
     done 
     return $rc 
} 

install_pkg() 
{ 
     pkg_name=$* 
     prompt="Install "$pkg_name"?" 
     show_yes_no_prompt $prompt 
     if [ $? -eq $g_cancel ]; then 
       exit 0 
     fi 
     if [ $? -eq $g_yes ]; then 
       apt-get install -y $pkg_name 
     else 
       echo "Installation of "$pkg_name" refused."  
     fi 
} 

當我寫install_pkg package1 package2提示將只顯示「安裝」,但我需要提示要像「安裝package1 package2'。那麼,這個代碼有什麼問題?

+1

你從哪裏調用'install_pkg'函數? –

+0

來自同一個腳本文件。 –

+0

你正在使用'bash'; hashbang應該是'#!/ bin/bash',而不是'#!/ bin/sh'。 – chepner

回答

1

你引用的東西都是混淆的。你想引用變量擴展。

所以你想要prompt="Install $pkg_name?"show_yes_no_prompt "$prompt"等,而不是prompt="Install "$pkg_name"?"show_yes_no_prompt $prompt

這裏發生的事情是要傳遞的$prompt每個字作爲一個單獨的參數show_yes_no_prompt(這是給你貼上他們都回來了,在功能$*合精十歲上下,但你不能處理包的通知這種方式正確的名字空間)。

問題是,那麼當你在函數中使用$prompt你不要引用它,它就會再次分裂read-p說法只看到第一個字和顯示這一切都顯示了(然後獲取你的「變量名」後,由於pkg(ync)是不是一個有效的標識符混淆。

你也別給yn閱讀作爲參數,這樣就不會爲它分配讀取到那裏的價值。

腳本的修正版本如下

#!/bin/sh 

g_yes=0 
g_no=-1 
g_cancel=1 
g_none=127 

show_yes_no_prompt() 
{ 
     rc=$g_none 
     while true; do 
       read -r -p "$* (ync): " yn 
       case $yn in 
         [Yy]*) rc=$g_yes; break;; 
         [Nn]*) rc=$g_no; break;; 
         [Cc]*) rc=$g_cancel; break;; 
         *) echo "Please answer yes/no/cancel.";; 
       esac 
     done 
     return $rc 
} 

install_pkg() 
{ 
     pkgs=("[email protected]") 
     show_yes_no_prompt "Install ${pkgs[*]}?" 
     if [ $? -eq $g_cancel ]; then 
       exit 0 
     fi 
     if [ $? -eq $g_yes ]; then 
       apt-get install -y "${pkgs[@]}" 
     else 
       echo "Installation of ${pkgs[*]} refused."  
     fi 
} 

請注意我是如何使用數組在install_pkg函數中存儲[email protected]的。這是正確/安全地處理任意包名稱的唯一方法。

-r參數read幾乎總是你想要的,並防止read解釋/吞嚥反斜槓轉義。

還要注意的是,在一般情況下,@擴展是優選的(也應該總是被引用)到*膨脹投入串膨脹時除外,其中單個串是必要的,這種情況下,*膨脹是必要的) 。

另請注意,您將永遠不會從函數返回-1。相反,您將獲得255

1

這是錯行:

read -p $prompt"(ync): " 

$prompt包含空格,所以read將採取只$prompt的第一個字。解決方法是,將$prompt包含在"中,因此確保它是整個字符串。

在bash使用"字符串時

read -p "$prompt (ync): " yn 

一般來說,取代它,你可以直接使用的變量。沒有必要拆分字符串。如果你不想要空格,你可以像這樣限制變量的名字:

read -p "${prompt}(ync): " yn 
+0

我剛剛嘗試過,現在提示顯示所有參數。但現在我得到了無限循環! –

+0

解釋爲什麼會顯着改善這個答案。 –

+0

@Maria_Wang是的,也就是說,因爲你沒有聲明或填充變量'$ yn',所以你的case語句總是失敗。看到我編輯的答案 – Slizzered