![bash 中具有动态结果的动态变量](https://linux22.com/image/161385/bash%20%E4%B8%AD%E5%85%B7%E6%9C%89%E5%8A%A8%E6%80%81%E7%BB%93%E6%9E%9C%E7%9A%84%E5%8A%A8%E6%80%81%E5%8F%98%E9%87%8F.png)
dubdub_count=3
for (( i=1; i<=${dubdub_count}; i++ )); do
my_apps --ammount=${dubdub_count}
done
程序将返回 IP 地址示例结果
app1=10.10.10.1
app2=10.10.10.2
app3=10.10.10.3
这些IP地址将用于其他服务。我正在创建一个 apiserver.sh bash 脚本来运行 apiserver 命令,如下所示
/usr/local/bin/apiserver --dubdub=http://${app1},http://${app2},http://{app3} --master
我希望我的 apiserver.sh 能够从 my_apps 结果添加动态结果。
如果我更改dubdub_count=3
为dubdub_count=4
我的脚本必须能够像这样运行
/usr/local/bin/apiserver --dubdub=http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3,http://10.10.10.4 --master
如果我更改dubdub_count=3
为dubdub_count=5
我的脚本必须能够像这样运行
/usr/local/bin/apiserver --dubdub=http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3:8080,http://10.10.10.4:8080,http://10.10.10.5:8080 --master
摘要问题是如何将 my_app 结果自动添加到--dubdub
参数中?如果 my_app 返回 6 个 IP 地址,我的 --dubdub 也将获得 6 个 IP 地址。我不需要手动编辑 bash 脚本。
我已经dynamic var in bash
在 stackoverflow 中阅读了 as 关键字,但仍然找不到最佳解决方案。我应该建议 my_apps 开发人员更改结果方法吗?
答案1
您可以添加http://
并:8080
使用sed
, 然后paste -sd,
将它们放在一起并用逗号分隔:
urllist=$(
for ... done \
| cut -d= -f2 \
| sed 's#.*#http://&:8080#' \
| paste -sd, -
) # output: http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3:8080
/usr/local/bin/apiserver --dubdub="$urllist" --master
cut
或者在一个命令中将,sed
和paste
part 一起执行awk
:
urllist=$(
for ... done \
| awk -F= 'NR>1{printf ","};{printf "http://"$2":8080"}'
) # output: http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3:8080
/usr/local/bin/apiserver --dubdub="$iplist" --master
答案2
从...开始:
$ seq -f "http://10.10.10.%g:8080" 1 3
http://10.10.10.1:8080
http://10.10.10.2:8080
http://10.10.10.3:8080
然后你可以把它变成一个函数:
$ ddcount() { seq -f "http://10.10.10.%g:8080" "$@" ; }
$ ddcount 5 7
http://10.10.10.5:8080
http://10.10.10.6:8080
http://10.10.10.7:8080
(注意:因为这只是将所有参数传递给命令seq
,所以 FIRST 参数是可选的,默认为 1。 ieseq 3
与 相同seq 1 3
, 与ddcount 3
相同ddcount 1 3
。如果需要,您也可以指定增量。请参阅man seq
详情)
将其与另一个函数结合使用分隔符(例如逗号)连接参数:
$ join_by() { local d=$1; shift; printf '%s' "$1"; shift; printf '%s' "${@/#/$d}"; }
这是以 perljoin()
函数为模型的,但命名join_by
是为了不与join
命令冲突。第一个参数是分隔符。其余参数是要连接的数据。
$ join_by , $(ddcount 1 3)
http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3:8080
注意:不要对$(ddcount 1 3)
函数调用使用双引号 - 你想它返回的字符串将被分词为多个项目,而不是仅被视为一个长字符串。比较上述命令的输出以join_by , "$(ddcount 1 3)"
查看差异。
最后,将所有这些放在一起:
start=1; stop=3
/usr/local/bin/apiserver --dubdub="$(join_by , $(ddcount "$start" "$stop"))" --master
或者
dd="$(join_by , $(ddcount "$start" "$stop"))"
/usr/local/bin/apiserver --dubdub="$dd" --master
答案3
假设您可以将第一个循环放入其自己的脚本中或放入名为的 shell 函数中my_apps_loop
(或者您可以将其插入到my_apps_loop
下面的调用中)。
#!/bin/bash
urls=()
# Create URLs
while IFS='=' read -r app ip; do
urls+=( "http://$ip:8080" )
done < <(my_apps_loop)
(
IFS=','
# Call apiserver with generated URLs
/usr/local/bin/apiserver --dubdub="${urls[*]}" --master
)
这将循环读取部分 into的输出my_apps_loop
(这将输出带有app1=...
等的行)以及into后面的字符串。appN
$app
=
$ip
对于读取的每一行,该$ip
位都会以字符串 开头http://
,以 为后缀:8080
,并插入到数组 中urls
。
最后的子 shell 调用apiserver
.该--dubdub
选项从urls
数组中获取其值,并将数组的值连接成一个以逗号分隔的字符串。