2017-04-22 63 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