重新初始化作为变量创建的变量

时间:2017-04-22 10:23:09

标签: bash

我有一个包含变量名的数组。在这些变量中,我使用循环分配值。然后我传递这些变量名称与指定值或另一个函数,它检查有效输入。

我需要做的是检查变量的值是否包含特定符号,如果是,则截断该值。

示例:当询问“管理网关:”时,我输入例如值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 个答案:

答案 0 :(得分:1)

好的,我发现了问题,当您尝试在declare $1使用check_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