我有一个包含变量名的数组。在这些变量中,我使用循环分配值。然后我传递这些变量名称与指定值或另一个函数,它检查有效输入。
我需要做的是检查变量的值是否包含特定符号,如果是,则截断该值。
示例:当询问“管理网关:”时,我输入例如值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
答案 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