我正在 CentOS 7.5 上编写一个 bash 脚本,它将执行一些 MongoDB 命令。这些命令之一将设置复制服务器。根据项目的不同,服务器的数量可以不同。
我有一个关联数组,它是服务器的主机名和 IP(我使用关联数组是因为代码的其他部分需要它)。在此示例中,我有三台服务器:
declare -A rep_hostname
rep_hostname=( [test1]='172.1.1.1' [test2]='172.1.1.2' [test3]='172.1.1.3' )
当拥有三台服务器时,我必须运行以下命令:
rs.initiate( { _id : "opino-rs", members: [ { _id: 0, host: "172.1.1.1:2701" },
{ _id: 1, host: "172.1.1.2:2701" }, { _id: 2, host: "172.1.1.3:2701" } ]})
如果我的阵列有两个服务器,我有这个:
rs.initiate( { _id : "opino-rs", members: [ { _id: 0, host: "172.1.1.1:2701" },
{ _id: 1, host: "172.1.1.2:2701" } ]})
我需要生成这个命令然后执行它。问题是我无法生成它。我尝试了一些代码,它们甚至与我想要的不接近。
我怎样才能做到这一点?
答案1
#!/bin/bash
declare -A rep_hostname
rep_hostname=( [test1]='172.1.1.1' [test2]='172.1.1.2' [test3]='172.1.1.3' )
json=$(
jo _id=opino-rs members="$(
jo -a "${rep_hostname[@]/%/:2701}" |
jq -c 'to_entries | map({ "_id": .key, "host": .value })'
)"
)
printf 'rs.initiate(%s)\n' "$json"
测试:
$ bash script.sh
rs.initiate({"_id":"opino-rs","members":[{"_id":0,"host":"172.1.1.3:2701"},{"_id":1,"host":"172.1.1.2:2701"},{"_id":2,"host":"172.1.1.1:2701"}]})
这同时使用jo
和jq
。该jo
实用程序是一个在 shell 中创建 JSON 的工具。jo
将确保生成的 JSON 被正确引用和编码。该jq
实用程序是一个在 shell 中解析和处理 JSON 的工具。
我用于jo
根据关联数组中的 IP 地址列表创建主机名的 JSON 列表。在创建 JSON 数组之前,我:2701
通过参数替换的方式添加到每个 IP 地址的末尾。
$ jo -a "${rep_hostname[@]/%/:2701}"
["172.1.1.3:2701","172.1.1.2:2701","172.1.1.1:2701"]
读取此内容并将其修改为我们要分配给最终 JSON 中的键jq
的 JSON 对象列表:members
$ jo -a "${rep_hostname[@]/%/:2701}" | jq -c 'to_entries | map({ "_id": .key, "host": .value })'
[{"_id":0,"host":"172.1.1.3:2701"},{"_id":1,"host":"172.1.1.2:2701"},{"_id":2,"host":"172.1.1.1:2701"}]
这将再次用作jo
构建最终 JSON 文档的输入。
rs.initiate()
在脚本的末尾,生成的 JSON 文档只需使用调用插入到字符串的括号中printf
。
由于我不使用 MongoDB,所以我无法说出如何以最佳方式执行此结果。
也可以看看: