2017-04-22 69 views
2

我有一個包含變量名稱的數組。在這些變量中,我使用循環來分配值。然後,我將這些變量名稱與另一個函數分配給另一個函數,該函數檢查有效輸入。重新初始化創建爲變量的變量

我需要做的是檢查變量的值是否包含特定的符號,如果是,則截斷該值。

例子:當被問及對「管理網關:」我爲例如值192.168.1.254/20(這是廢話)進入,我想這個值被截斷爲192.168.1.254

在初始化$1="something"不工作,它返回錯誤admGW=192.168.1.254: command not found

我試過類似declare $1="something",但這隻會創建另一個局部變量在當前函數中可見。我需要重新初始化現有的全局變量。這可能不是最好的方法,但我很好奇這種變量初始化是否可行。

示例代碼:

#!/bin/bash 
read_variables(){ 
    all_vars_desc=("Admin IP/mask: " "Admin gateway: ") 
    all_vars_name=("admIP" "admGW") 

    for ((i=0; i<${#all_vars_desc[*]}; i++)); do 
     read -p "${all_vars_desc[$i]}" ${all_vars_name[$i]} 
     check_value ${all_vars_name[$i]} "${!all_vars_name[$i]}" 
    done 
} 

check_value(){ 
    case $1 in 
     *IP) ;; #some code 
     *GW) if [[ "$2" == */* ]]; then 
       $1=$(echo "$2" | awk -F/ '{print $1}') 
       echo "Truncating to ${!1}" 
      fi;; 
    esac 
} 

read_variables 

回答

1

好吧,我想通了這個問題,當您嘗試使用上$1declarecheck_value()變量定義只限於局部範圍,但declare有用於製作-g標誌變量全局。行

$1=$(echo "$2" | awk -F/ '{print $1}') 

更改爲

delcare -g "$1"=$(echo "$2" | awk -F/ '{print $1}') 

查看更多有關declare built-in命令。

我修改你的腳本打印在腳本結束的元素,如下面和

for ((i=0; i<${#all_vars_name[*]}; i++)); do 
    echo ${!all_vars_name[$i]} 
done 

與調試模式(bash -x)現在正在運行,它產生的結果,你需要,

$ bash -x script.sh 
+ read_variables 
+ all_vars_desc=("Admin IP/mask: " "Admin gateway: ") 
+ all_vars_name=("admIP" "admGW") 
+ ((i=0)) 
+ ((i<2)) 
+ read -p 'Admin IP/mask: ' admIP 
Admin IP/mask: 1.1.1.1/32 
+ check_value admIP 1.1.1.1/32 
+ case $1 in 
+ ((i++)) 
+ ((i<2)) 
+ read -p 'Admin gateway: ' admGW 
Admin gateway: 2.2.2.2/32 
+ check_value admGW 2.2.2.2/32 
+ case $1 in 
+ [[ 2.2.2.2/32 == */* ]] 
++ echo 2.2.2.2/32 
++ awk -F/ '{print $1}' 
+ declare -g admGW=2.2.2.2 
+ echo 'Truncating to 2.2.2.2' 
Truncating to 2.2.2.2 
+ ((i++)) 
+ ((i<2)) 
+ ((i=0)) 
+ ((i<2)) 
+ echo 1.1.1.1/32 
1.1.1.1/32 
+ ((i++)) 
+ ((i<2)) 
+ echo 2.2.2.2 
2.2.2.2 
+ ((i++)) 
+ ((i<2)) 

並在正常模式下,確認變量值在主功能中更新

$ bash script.sh 
Admin IP/mask: 1.1.1.1/32 
Admin gateway: 2.2.2.2/32 
Truncating to 2.2.2.2 
1.1.1.1/32 
2.2.2.2 

由於OP的相對較舊版本bash,並且declare -g僅可從bash 4.2起。在舊bash版本,您仍然可以刪除與declare行和間接變量擴展下一行,只是做

eval "$(printf %s=%q "$1" "$(echo "$2" | awk -F/ '{print $1}')")" 

既然你在這裏使用eval,你需要絕對的把握消毒的右手邊即正確的方式瞭解絕對確保您傳遞$2什麼,看到BashFAQ/006下分配間接/引用變量

+0

感謝您的回答。我也曾嘗試在屬性「-g」之前聲明(抱歉,我沒有提及它),但在我的CentOS虛擬機中沒有屬性「-g」。 '聲明[-aAfFilrtux] [-p] [名稱[=值] ...]'。我不確定它是否會出現在目標系統上。沒有任何其他方式如何實現預期的結果? 「否」也可以作爲答案:D – Lopfest

+0

@Lopfest:它不是關於CentOS機器,你有一個過時的'bash'版本。認爲你可以升級它?你能向我們展示'bash --version'嗎? – Inian

+0

當然。 'GNU bash,版本4.1.2(2) - 發佈(x86_64-redhat-linux-gnu)' – Lopfest