2013-06-06 2 views
0

У меня есть приложение, которое запускает и определяет устройства в системе. Результат выглядит примерно так:Bash - назначить переменные для вывода команды в цикле

./show-devices 192.168.1.2 | grep volume 

/dev/sda  volumeid-65 
/dev/sdb  volumeid-81 
/dev/sdc  volumeid-92 

То, что я пытаюсь сделать, это запустить приложение в цикле и назначить переменные следующим образом:

sda=volumeid-65 
sdb=volumeid-81 
sdc=volumeid-92 

Затем, быть в состоянии использовать $ SDA , $ sdb и $ sdc в дальнейшем. Не все выходы одинаковы. У некоторых машин будет только один том, у некоторых будет больше. Все предложения приветствуются. Я пробовал много комбинаций цикла for и, кажется, никуда не денусь. Спасибо!

ответ

1

Как насчет:

eval `./show-devices 192.168.1.2 | grep volume | while read d v ;do 
    echo $(basename $d)=$v 
done` 

Однако, вы не убедитесь, что имена переменных. Так что лучше использовать ассоциативный массив:

# declare the array 
declare -A volumes 

# Assign values to the array 
eval `./show-devices 192.168.1.2 | grep volume | while read d v ;do 
    echo volumes[$(basename $d)]=$v 
done` 

# Use the array 
for i in "${!volumes[@]}"; do 
    echo "Key:$i , Value:${volumes[$i]}" 
    # Declare all the variables with the values as asked by question 
    eval $i=${volumes[$i]} 
done 

Explaination: | while read d v петли над выходом предыдущей команды чтения 2 значения для каждой строки. basename $d дает мне базовое имя устройства, а $ v содержит том, связанный с устройством. Он присваивается ассоциативному массиву volumes, объявленному declare -A volumes. Цикл while работает под суб-оболочкой, и отпечатки volumes[sda]=... и eval оценивают это в текущей оболочке, фактически присваивая значение.

Использование: Цикл for является примером использования. "${!volumes[@]}" - это список ключей для массива volumes, а цикл for петли над ними и печатает значение, связанное с каждым ключом в массиве volumes.

редактирует:

  • Modified петля while для эха распайки и eval всей вещь (чтобы обойти субоболочку будучи порождением трубы

  • Добавлена ​​информация Использования

  • .
  • Добавлено точное решение, заданное под вопросом

+1

Вы попробовали этот код? bash выполнит 'while ...' в подоболочке; когда труба заканчивается, то и подоболочка вместе со связанными с ней переменными. – rici

+0

@rici Вы правы. Изменение решения для работы над подоболочкой. – Samveen

+0

Спасибо. Как мне позже ссылаться на массив, чтобы использовать элементы в нем? –

0
source <(
    ./show-devices 192.168.1.2 | 
    sed -rn '/volume/{s#/dev/([^[:space:]]+)[[:space:]]+#\1=#;p}' 
) 

Это запускает вашу команду, проходит через СЭД, чтобы отформатировать его как присвоения оболочки, а затем использует замену процесса для лечения выхода, как файл, который соерсед в текущую оболочку.

Смежные вопросы