gpt4 book ai didi

Using Bash variable indirection with combined variable(将Bash变量间接与组合变量一起使用)

转载 作者:bug小助手 更新时间:2023-10-24 20:20:19 35 4
gpt4 key购买 nike



I have a script that configured multiple "jobs" based on environment variables. The script performs internal iteration to and reads configuration from prefixed variables (e.g. timeout_job_1=30). Some, but not all, variables also have defaults, to be used when no job-specific one isn't available (e.g. timeout=10).

我有一个基于环境变量配置多个“作业”的脚本。该脚本对前缀变量执行内部迭代并从其读取配置(例如,TIMEOUT_JOB_1=30)。一些(但不是全部)变量也有缺省值,当没有特定于作业的变量不可用时使用(例如,超时=10)。


Example:

示例:


#!/usr/bin/env bash

#### Externally set variables
defaultValA="default value for A"
defaultValC="default value for C"
valA_1="A for iter 1"
valB_2="B for iter 2"

for((i=1; i<=2; i++)); do
valA="valA_$i" ; valA="${!valA:-${defaultValA:-}}"
valB="valB_$i" ; valB="${!valB:-${defaultValB:-}}"
valC="valC_$i" ; valC="${!valC:-${defaultValC:-}}"

echo "Iteration #$i val A: ${valA}"
echo "Iteration #$i val B: ${valB}"
echo "Iteration #$i val C: ${valC}"

echo "---------"
done

Is there a way to avoid the temporary variables on top of the loop, and somehow assign valA-valC directly? I can use eval but that doesn't seem elegant.

有没有一种方法可以避免循环顶部的临时变量,并以某种方式直接赋值Vala-Valc?我可以用eval,但这看起来不太优雅。


更多回答

Any time you think you need to create a variable name on the fly is generally a big clue that you should be using associative arrays instead. declare -A timeouts; timeout[job_1]=30 etc

在您认为需要动态创建变量名的任何时候,通常都会提示您应该改用关联数组。声明-A超时;超时[JOB_1]=30等

@Shawn: I fully agree on principle. However, many tools (including very popular ones like Docker Compose as per github.com/docker/compose/issues/4249) do not support any arrays, even simple lists. In addition, in this case it would make sense to use nested associative array in a form of job[0][timeout], which even bash will not support. This is why the whole code uses suboptimal dynamic variable names.

@Shawn:原则上我完全同意。然而,许多工具(包括非常流行的工具,如Docker,按照githorb.com/docker/Compose/Issues/4249编写)不支持任何数组,甚至不支持简单的列表。此外,在这种情况下,以JOB[0][TIMEOUT]的形式使用嵌套关联数组是有意义的,即使bash也不支持。这就是为什么整个代码使用不太理想的动态变量名称。

@kiler129: docker-compose is primary meant for testing purpose. Better use docker run with proper arguments, and associative arrays in a bash script if required.

@kier129:Docker-Compose主要用于测试目的。如果需要,最好在bash脚本中使用带有正确参数的docker run和关联数组。

You can usually emulate multidimensional arrays in bash very effectively with a single associative array by creating compound keys. echo ${v[1,0]} # one, zero This is efficient, and though it needs careful quoting in some cases, is simpler that multiple compound indirection, and likely a lot easier to maintain and debug. This will be a nightmare behind layers of container, yaml, possibly helm, dockerfiles, sidecars, and more...

通过创建复合键,您通常可以非常有效地使用单个关联数组在bash中模拟多维数组。ECHO${v[1,0]}#1,0这是高效的,尽管在某些情况下需要仔细引用,但它比多个复合间接连接更简单,而且可能更易于维护和调试。这将是一场噩梦,隐藏在容器、YAML、可能的Helm、码头文件、侧车和更多的层后面……

Since i is a "small" integer, why aren't you using indexed arrays, so that you hav `valA=${valA_[$i]:-default}?

既然i是一个“小”整数,为什么不使用索引数组,这样您就得到了`valA=${Vala_[$i]:-Default}?

优秀答案推荐

Using a one dimensional associative array with compound keys to emulate multidimensional lookups.

使用带有复合键的一维关联数组来模拟多维查找。


declare -A v=( ["A,0"]="default value for A" 
["A,1"]="A for iter 1"
["B,2"]="B for iter 2"
["C,0"]="default value for C" ) # leaving holes is fine
for i in 1 2
do for l in A B C
do echo $i,$l: ${v["$l,$i"]:-${v["$l,0"]}}
done
done
1,A: A for iter 1
1,B:
1,C: default value for C
2,A: default value for A
2,B: B for iter 2
2,C: default value for C

No temp vars beside the loop iterators, no eval.

除了循环迭代器之外,没有临时变量,也没有取值。


更多回答

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com