Назад | Перейти на главную страницу

Как в цикле сослаться на значение созданной переменной среды?

Я пытаюсь перебрать переменные среды. У меня есть несколько установок, которые меняются, и каждая установка имеет 3 IP-адреса для отправки файлов и запуска сценариев, и я хочу максимально автоматизировать это (так что мне нужно только изменить файл, который я буду источником с переменные среды). Ниже приводится упрощенная версия, которая, как только я пойму, могу решить свою проблему.

Так указано в my.props:

COUNT=2
A_0=foo
B_0=bar
A_1=fizz
B_1=buzz

Я хочу заполнить цикл for следующим скриптом

#!/bin/bash
. <path>/my.props

for ((i=0; i < COUNT; i++))
do
  <script here>
done

Чтобы я мог получить значения из переменных окружения. Примерно так (но это действительно работает):

echo $A_$i $B_$i

или

A=A_$i
B=B_$i
echo $A $B

возвращает foo bar, затем fizz buzz

$ num=0
$ declare A_$num=42  # create A_0 and set it to 42
$ echo $A_0
42
$ b=A_$num           # create a variable with the contents "A_0"
$ echo ${!b}         # indirection
42

Вы можете повторять num и использовать declare для создания переменных и косвенного обращения к ним. Но разве вы не предпочли бы использовать массивы?

for i in foo bar baz
do
    some_array+=($i)    # concatenate values onto the array
done

или

string="foo bar baz"
some_array=($string)

Как насчет этого?

$ cat IPs
192.168.0.1
192.168.0.2
192.168.0.3
$ cat readips
#!/bin/bash
while read -r ip
do
    IP[count++]=ip                 # is it necessary to save them in an array,
    do_something_directly_with ip  # if you use them right away?
done < IPs
A=`eval echo \$A_$i`

Нашел ответ на Косвенные ссылки Глава Advanced Bash Scripting Guide

Мне нужно было сделать

eval A=\$A_$i
eval B=\$B_$i

Не уверен, что я полностью понимаю ваш вопрос, но если вы хотите, чтобы переменные были доступны для дочерних скриптов, используйте export встроенный:

kbrandt@kbrandt:~/scrap$ help export
export: export [-nf] [name[=value] ...] or export -p
    NAMEs are marked for automatic export to the environment of
    subsequently executed commands.

Судя по тому, что вы, возможно, пытаетесь сделать, я бы просто поместил IP-адреса в один файл, по одному IP-адресу на строку. Затем пусть сценарий установки прочитает ip как аргумент командной строки:

while read ip; do
   ./install-script "$ip"
done < file_with_ips

Если в каждой записи содержится более одного фрагмента данных, их можно разделить:

kbrandt@kbrandt:~/scrap$ cat file_with_data 
192.168.2.5:foobar:baz
kbrandt@kbrandt:~/scrap$ while IFS=":" read -r ip data1 data2; do 
> echo "$ip@$data1@$data2"
> done < file_with_data
192.168.2.5@foobar@baz