循环变量

循环变量

我正在编写一个 bash 脚本来使用 rsync 并更新大约 20 个不同服务器上的文件。

我已经弄清楚了 rsync 部分。我遇到的麻烦是浏览变量列表。

到目前为止我的脚本看起来像这样:

#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"

for ((i=1; i<7; i++))
do
    echo [Server IP Address]
done

其中[Server IP Address]应该是关联变量的值。因此,当 i = 1 时,我应该回显 $SERVER1 的值。

我已经尝试过几次迭代,包括

echo "$SERVER$i"    # printed the value of i
echo "SERVER$i"     # printer "SERVER" plus the value of i ex: SERVER 1 where i = 1
echo $("SERVER$i")  # produced an error SERVER1: command not found where i = 1
echo $$SERVER$i     # printed a four digit number followed by "SERVER" plus the value of i
echo \$$SERVER$i    # printed "$" plus the value of i

自从我编写脚本以来已经很长时间了,所以我知道我错过了一些东西。另外,我确信我正在混合使用 C# 可以做的事情,我已经使用了 C# 11 年了。

我想做的事情可能吗?或者我应该将这些值放入数组中并循环遍历该数组?对于生产 IP 地址和位置名称,我也需要同样的东西。

这一切都是为了不必重复我将用来同步远程服务器上的文件的代码块。

答案1

使用数组。

#! /bin/bash
servers=( 192.xxx.xxx.2 192.xxx.xxx.3
          192.xxx.xxx.4 192.xxx.xxx.5
          192.xxx.xxx.6 192.xxx.xxx.7
)

for server in "${servers[@]}" ; do
    echo "$server"
done

答案2

正如其他答案所指出的,数组是执行此操作的最方便的方法。但是,为了完整起见,您要求的确切内容是间接扩张。重写如下,您的示例也将使用此方法工作:

#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"

for ((i=1; i<7; i++))
do
    servervar="SERVER$i"
    echo "${!servervar}"
done

如果您同意将 IP 地址列表放入循环中for,那么您也可以考虑简单地使用一些大括号扩展来迭代您需要的任何内容:

#!/bin/bash

for server in \
192.xxx.xxx.{2..7} \
192.yyy.yyy.{42..50} \
192.zzz.zzz.254
do
    echo "$server"
done

但是如果您需要重用(可能是大括号扩展的)列表,那么使用列表来初始化数组将是正确的方法:

#!/bin/bash

servers=(
192.xxx.xxx.{2..7} 
192.yyy.yyy.{42..50}
192.zzz.zzz.254 )

for server in "${servers[@]}"
do
    echo "$server"
done

答案3

虽然我自己可能会选择数组答案之一,但我想指出可以直接循环名称。你可以做

for name in "${!SERVER*}"; do
    echo "${!name}"
done

或者,在 4.3 及更高版本中,您可以使用nameref

declare -n name
for name in "${!SERVER*}"; do
    echo "$name"
done

帽尖伊尔卡丘针对 < 4.3 解决方案。

答案4

每个说你应该使用数组的人都是正确的,但是——作为一项学术练习——如果你决定使用以数字结尾的单独变量(SERVER1、SERVER2 等)来做到这一点,那么你就会这样做它:

for ((i=1; i<7; i++))
do
    eval echo \"\$SERVER$i\"
done

相关内容