Estoy escribiendo un script bash para usar rsync y actualizar archivos en unos 20 servidores diferentes.
Tengo la parte rsync resuelta. Lo que me está costando es revisar una lista de variables.
Mi script hasta ahora se ve así:
#!/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
Donde [Server IP Address]
debe ser el valor de la variable asociada. Entonces, cuando i = 1, debería hacer eco del valor de $ SERVER1.
He intentado varias iteraciones de esto, incluyendo
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
Ha pasado mucho tiempo desde que escribí el guión, así que sé que me falta algo. Además, estoy seguro de que estoy mezclando lo que podría hacer con C #, que he usado durante los últimos 11 años.
¿Es posible lo que intento hacer? ¿O debería poner estos valores en una matriz y recorrer la matriz? Necesito lo mismo para las direcciones IP de producción, así como los nombres de ubicación.
Todo esto es un esfuerzo para no tener que repetir un bloque de código que usaré para sincronizar los archivos en el servidor remoto.
fuente
Respuestas:
Usa una matriz.
fuente
Como señalan las otras respuestas, una matriz es la forma más conveniente de hacer esto. Sin embargo, para completar, exactamente lo que está pidiendo es una expansión indirecta . Reescrito de la siguiente manera, su muestra también funcionará usando este método:
Si está de acuerdo con solo poner la lista de direcciones IP en el
for
bucle, entonces también podría considerar simplemente usar algunas expansiones de llaves para iterar sobre lo que necesite:Pero si necesita reutilizar la lista (posiblemente expandida entre corchetes), usar la lista para inicializar una matriz sería el camino a seguir:
fuente
Si bien probablemente iría con una de las respuestas de la matriz yo mismo, me gustaría señalar que es posible recorrer los nombres directamente. Tu puedes hacer
o, en 4.3 y versiones posteriores, puede usar un
nameref
:Hat tip ilkkachu para la solución <4.3.
fuente
${!var}
) también funciona con versiones anteriores de Bash:foo1=aa; foo2=bbb; foox=cccc; for p in "${!foo@}"; do echo "$p = ${!p}"; done
Todos los que dijeron que debería usar una matriz son correctos, pero, como ejercicio académico, si estuviera decidido a hacerlo con variables separadas que terminen en un número (SERVER1, SERVER2, etc.), así es como lo haría eso:
fuente
eval
Es difícil de usar de forma segura. Sí, esto puede funcionar, pero bash expansión indirecta es una mejor manera en general.eval
hecho esto, no lo haecho $SERVER1
hechoecho "$SERVER1"
. Sí, es posible usarlo de manera segura, ¡pero es muy fácil de usar de manera insegura o no como pretendía!