bash脚本 - 如何处理逗号分隔列表作为输入参数的函数
问题描述:
我想弄清楚如何传递逗号分隔的列表作为输入,并让我的函数一次处理一个值。bash脚本 - 如何处理逗号分隔列表作为输入参数的函数
我的功能:
addToWhitelist()
{
host='127.0.0.1'
db='mytest'
_mongo=$(which mongo);
echo "${_ip}";
read -a arr <<<${_ip};
for i in ${arr[@]};
do
exp="db.account.update({\"account\":'${_account}'},{\$addToSet:{\"ip_list\": {\$each:['${_ip}'] }}})";
${_mongo} ${host}/${db} --eval "$exp"
done
}
我跑我的脚本是这样的:
./myscript.sh -m add -a pizzahut -i 123.456.790.007,123.456.790.008
我正在进行代码:
#!/usr/local/bin/bash
set -e
set -x
# Usage for getopts
usage() {
echo "Example: $0 -m find -a pizzahut"
echo "Example: $0 -m add -a pizzahut -i 10.10.123.456"
exit 1;
}
while getopts ":m:a:i:" o; do
case "${o}" in
m)
_mode=${OPTARG}
if [[ "${_mode}" != find && "${_mode}" != add ]]; then
usage
fi
;;
a)
_account=${OPTARG}
;;
i)
_ip=${OPTARG}
set -f
IFS=,
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
getWhitelist()
{
host='127.0.0.1'
db='mytest'
_mongo=$(which mongo);
exp="db.account.find({\"account\":'${_account}'},{ip_list: 1}).pretty();";
${_mongo} ${host}/${db} --eval "$exp"
}
# Read a list
addToWhitelist()
{
host='127.0.0.1'
db='mytest'
_mongo=$(which mongo);
echo "${_ip}";
read -a arr <<<${_ip};
for i in ${arr[@]};
do
exp="db.account.update({\"account\":'${_account}'},{\$addToSet:{\"ip_list\": {\$each:['${_ip}'] }}})";
${_mongo} ${host}/${db} --eval "$exp"
done
}
case "${_mode}" in
'find')
echo "Finding information for the account ${_account}"
getWhitelist
;;
'add')
echo "Adding the following IP: ${_ip}"
addToWhitelist
;;
esac
set +x
不过,我遇到的问题当我调用该函数时,将值插入单个字符串:
"ip_list" : [
"123.456.790.006",
"123.456.790.007,123.456.790.008",
"123.456.790.009"
]
}
期待:
"ip_list" : [
"123.456.790.006",
"123.456.790.007",
"123.456.790.008",
"123.456.790.009"
]
}
答
因为你的脚本接收到一个逗号分隔的IP地址列表,有效的是这样的:
_ip="123.456.790.007,123.456.790.008"
你需要,
分裂列表,并给它蒙戈的$each
操作之前报价包装每个IP。
首先,本地化的IFS
重新定义到read
命令只,然后利用重用相同的格式字符串时提供更多的参数(该膨胀阵列"${arr[@]}"
),经由-v
选项将结果存储到一个变量的printf
的行为,和钢带从结果前导,
:
IFS=, read -a arr <<<"${_ip}"
printf -v ips ',"%s"' "${arr[@]}"
ips="${ips:1}"
对于上面给出的_ip
值,该脚本将存储在ips
变量:
"123.456.790.007","123.456.790.008"
因此,将其应用到你的程序,首先改变你的i)
情况下,如:
case "${o}" in
# ...
i) _ip=${OPTARG};;
esac
然后修复addToWhitelist
功能:
addToWhitelist() {
host='127.0.0.1'
db='mytest'
_mongo=$(which mongo)
IFS=, read -a arr <<<"${_ip}"
printf -v ips ',"%s"' "${arr[@]}"
ips="${ips:1}"
exp="db.account.update({'account': '${_account}'}, {\$addToSet:{'ip_list': {\$each:[$ips]}}})";
"${_mongo}" "${host}/${db}" --eval "$exp"
}
答
以下尝试,
IP = $(回声$ {OPTARG} | sed的 “S /,/,\ N/G”)
所以完整的脚本就会这样,
#!/usr/local/bin/bash
set -e
set -x
# Usage for getopts
usage() {
echo "Example: $0 -m find -a pizzahut"
echo "Example: $0 -m add -a pizzahut -i 10.10.123.456"
exit 1;
}
while getopts ":m:a:i:" o; do
case "${o}" in
m)
_mode=${OPTARG}
if [[ "${_mode}" != find && "${_mode}" != add ]]; then
usage
fi
;;
a)
_account=${OPTARG}
;;
i)
_ip=$(echo ${OPTARG}|sed "s/,/,\n/g")
set -f
IFS=,
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
getWhitelist()
{
host='127.0.0.1'
db='mytest'
_mongo=$(which mongo);
exp="db.account.find({\"account\":'${_account}'},{ip_list: 1}).pretty();";
${_mongo} ${host}/${db} --eval "$exp"
}
# Read a list
addToWhitelist()
{
host='127.0.0.1'
db='mytest'
_mongo=$(which mongo);
echo "${_ip}";
read -a arr <<<${_ip};
for i in ${arr[@]};
do
exp="db.account.update({\"account\":'${_account}'},{\$addToSet:{\"ip_list\": {\$each:['${_ip}'] }}})";
${_mongo} ${host}/${db} --eval "$exp"
done
}
case "${_mode}" in
'find')
echo "Finding information for the account ${_account}"
getWhitelist
;;
'add')
echo "Adding the following IP: ${_ip}"
addToWhitelist
;;
esac
set +x
哇!非常感谢你的帮助。使用'printf'是处理这个问题的好方法。我感谢您的帮助! – noober