将多个variables与通配符合并为一个variables

我有这个脚本:

#!/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/\.[^.]*$//' ) 

然后我想在一个variables中处理ping_1-4的输出。 像这样的东西:

 #!/bin/bash if [ "$ping_*" -gt 50 ]; then echo "One ping is to high" else echo "The pings are fine" fi 

bash是否有可能使用某种通配符来读取这些variables?

 $ping_* 

对我没有任何帮助。

我不认为有这样的通配符。 但是您可以使用循环来遍历值,例如:

 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 

你所说的问题的答案是,是的,你可以用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. 

您的实际问题的答案是使用数组。

你可以使用“和”(-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 

用基于数组的解决方案来补充现有的有用答案,该解决方案演示:

  • 几种先进的Bash技术(强大的数组处理,复合条件,处理ping失败的情况)
  • 一个优化的方法,通过一个单一的sed命令(同时用于GNU和BSD / macOS sed )从ping的输出中提取平均时间。
  • 报告服务器花费太长时间或未能按名称响应。
 #!/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 

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 – 如果循环遍历所有的变量,然后打印“坪是好的”