我有这个脚本:
#!/bin/bash
ping_1=$(ping -c 1 www.test.com | tail -1| awk '{print $4}' | cut -d '/' -f 2 | sed 's/\.[^.]*$//')
ping_2=$(ping -c 1 www.test1.com | tail -1| awk '{print $4}' | cut -d '/' -f 2 | sed 's/\.[^.]*$//')
ping_3=$(ping -c 1 www.test2.com | tail -1| awk '{print $4}' | cut -d '/' -f 2 | sed 's/\.[^.]*$//')
ping_4=$(ping -c 1 www.test3.com | tail -1| awk '{print $4}' | cut -d '/' -f 2 | sed 's/\.[^.]*$//' )
然后我想在一个变量中处理ping_1-4
的输出。像这样:
#!/bin/bash
if [ "$ping_*" -gt 50 ]; then
echo "One ping is to high"
else
echo "The pings are fine"
fi
bash
是否有可能使用某种通配符读取这些变量?
$ping_*
对我没有任何帮助。
答案 0 :(得分:3)
你陈述的问题的答案是肯定的,你可以用bash中的参数扩展(但不是sh)来做到这一点:
#!/bin/bash
ping_1=foo
ping_2=bar
ping_etc=baz
for var in "${!ping_@}"
do
echo "$var is set to ${!var}"
done
将打印
ping_1 is set to foo
ping_2 is set to bar
ping_etc is set to baz
此处man bash
:
${!prefix*}
${!prefix@}
Names matching prefix. Expands to the names of variables whose
names begin with prefix, separated by the first character of the
IFS special variable. When @ is used and the expansion appears
within double quotes, each variable name expands to a separate
word.
您实际问题的答案是改为使用数组。
答案 1 :(得分:1)
我不认为有这样的通配符。 但您可以使用循环来迭代值,例如:
exists_too_high() {
for value; do
if [ "$value" -gt 50 ]; then
return 0
fi
done
return 1
}
if exists_too_high "$ping_1" "$ping_2" "$ping_3" "$ping_4"; then
echo "One ping is to high"
else
echo "The pings are fine"
fi
答案 2 :(得分:1)
您可以使用“和”( - a)参数:
if [ $ping_1 -gt 50 -a \
$ping_2 -gt 50 -a \
$ping_3 -gt 50 -a ]; then
...
...
或者不是定义很多变量,而是可以创建一个数组并检查循环:
pings+=($(ping -c 1 www.test.com | tail -1| awk '{print $4}' | cut -d '/' -f 2 | sed 's/\.[^.]*$//'))
pings+=($(ping -c 1 www.test1.com | tail -1| awk '{print $4}' | cut -d '/' -f 2 | sed 's/\.[^.]*$//'))
pings+=($(ping -c 1 www.test2.com | tail -1| awk '{print $4}' | cut -d '/' -f 2 | sed 's/\.[^.]*$//'))
pings+=($(ping -c 1 www.test3.com | tail -1| awk '{print $4}' | cut -d '/' -f 2 | sed 's/\.[^.]*$//' ))
too_high=0
for ping in ${pings[@]}; do
if [ $ping -gt 50 ]; then
too_high=1
break
fi
done
if [ $too_high -eq 1 ]; then
echo "One ping is to high"
else
echo "The pings are fine"
fi
答案 3 :(得分:0)
使用基于阵列的解决方案来补充现有的,有用的答案:
ping
命令从sed
输出中提取平均时间的优化方法(适用于GNU和BSD / macOS sed
)。 #!/usr/bin/env bash
# Determine the servers to ping as an array.
servers=( 'www.test.com' 'www.test1.com' 'www.test2.com' 'www.test3.com' )
# Initialize the array in which timings will be stored, paralleling the
# "${servers[@]}" array.
avgPingTimes=()
# Initialize the array that stores the names of the servers that either took
# too long to respond (on average), or couldn't pe pinged at all.
failingServers=()
# Determine the threshold above which a timing is considered too high, in ms.
# Note that a shell variable should contain at least 1 lowercase character.
kMAX_TIME=50
# Determine how many pings to send per server to calculate the average timing
# from.
kPINGS_PER_SERVER=1
for server in "${servers[@]}"; do
# Ping the server at hand, extracting the integer portion of the average
# timing.
# Note that if pinging fails, $avgPingTime will be empty.
avgPingTime="$(ping -c "$kPINGS_PER_SERVER" "$server" |
sed -En 's|^.* = [^/]+/([^.]+).+$|\1|p')"
# Check if the most recent ping failed or took too long and add
# the server to the failure array, if so.
[[ -z $avgPingTime || $avgPingTime -gt $kMAX_TIME ]] && failingServers+=( "$server" )
# Add the timing to the output array.
avgPingTimes+=( "$avgPingTime" )
done
if [[ -n $failingServers ]]; then # pinging at least 1 server took too long or failed
echo "${#failingServers[@]} of the ${#servers[@]} servers took too long or couldn't be pinged:"
printf '%s\n' "${failingServers[@]}"
else
echo "All ${#servers[@]} servers responded to pings in a timely fashion."
fi
答案 4 :(得分:0)
是bash
可以使用其内部$ping_
命令列出以compgen -v
开头的变量,(请参阅 SHELL BUILTIN COMMANDS 下的man bash
),即:
for f in `compgen -v ping_` foo ; do
eval p=\$$f
if [ "$p" -gt 50 ]; then
echo "One ping is too high"
break 1
fi
[ $f=foo ] && echo "The pings are fine"
done
注意添加的循环项foo
- 如果循环遍历所有变量,则打印" ping很好" 。