2015-01-27 2 views
3

Я пытаюсь написать сценарий bash, чтобы разрешить мне выбрать один массив среди множества различных массивов. Для этой цели, Я намерен использовать простую переменную для ссылки на один массив.Использование переменной оболочки для выбора одного массива bash

#!/bin/bash 
#To get all the members of a given array as the output 
#variables 
FIRST=(A B C D) 
SECOND=(planes cars trains bicycles gocarts) 
THIRD=(werewolfs vampires zombies ghosts daemons) 
FOURTH=(football soccer basketball rugby batmington zumo) 
FIFTH=(handguns rifles machineguns bazookas slingshots) 
SIXTH=(dogs cats turtles ferrets birds hamsters fish) 
SEVENTH=(monday tuesday wednesday thursday friday saturday sunday) 

#execution 
select ARRAY in "FIRST" "SECOND" "THIRD" "FOURTH" "FIFTH" "SIXTH" "SEVENTH"; do 
    OUTPUT=eval '"${'${ARRAY}'[@]}"' 
    echo $OUTPUT 
    break 
done 

#end 

выше скрипт не работает. До сих пор я пытался заменить линию 9 с этими параметрами:

OUTPUT=eval '$'{ARRAY'[@]'} 
OUTPUT=eval ${"$ARRAY"[@]} 
OUTPUT=eval ${'$ARRAY'[@]} 
OUTPUT=eval ${'$'ARRAY[@]} 
OUTPUT=eval '$'{"$ARRAY"[@]} 
OUTPUT=eval \${${ARRAY}[@]} 

Что я здесь отсутствует?

ответ

1

Это работает для меня:

#!/bin/bash 
#To get all the members of a given array as the output 
#variables 
FIRST=(A B C D) 
SECOND=(planes cars trains bicycles gocarts) 
THIRD=(werewolfs vampires zombies ghosts daemons) 
FOURTH=(football soccer basketball rugby batmington zumo) 
FIFTH=(handguns rifles machineguns bazookas slingshots) 
SIXTH=(dogs cats turtles ferrets birds hamsters fish) 
SEVENTH=(monday tuesday wednesday thursday friday saturday sunday) 

#execution 
ARRAY="FIFTH" 
select ARRAY in "FIRST" "SECOND" "THIRD" "FOURTH" "FIFTH" "SIXTH" "SEVENTH"; do 
    eval "OUTPUT=\${$ARRAY[*]}" 
    echo $OUTPUT 
    break 
done 

eval может быть использована для введения новых переменных. Мы строим строку, содержащую выражение, назначающее требуемое значение OUTPUT, а затем оцениваем его, вводя новую переменную OUTPUT с требуемым значением.

+0

К сожалению, я не конечно, я могу понять ваше решение. Как это может позволить мне выбрать один массив среди тех, которые я ранее определил, и распечатать все его элементы на выходе? Я снова извиняюсь, может быть, я слишком устал, чтобы увидеть это ... – user148854

+0

Извините, мне кажется, что я неправильно понял ваш вопрос изначально. Я обновил свой ответ, я думаю, что теперь он решает настоящую проблему. – nicebyte

+0

Это действительно проблема. Большое спасибо. – user148854

0

У меня есть. следующие работы для линии 9:

OUTPUT=$(eval echo \${${ARRAY}[@]}) 

Большое спасибо за ваше терпение с этой бедной маленькой ученицей :)

+0

не забудьте указать «репутацию», приняв ответ, который поможет вам. Как только вы превысите 16 очков, вы также можете получить ответы на голосование. .... Вы принимаете ответы путем зависания (hm ,, возможно, щелчка) на^0v на краю в левом верхнем углу полезного ответа. Вы увидите возможность щелкнуть по зеленой галочке. Всем удачи. – shellter

+0

Будет, когда я достигну 16+. Спасибо кучу :) – user148854

1

eval совершенно необязательно, чтобы решить эту проблему. Вы должны всегда думать дважды, прежде чем использовать eval из-за его хрупкости. (То есть ошибка может иметь катастрофические последствия.)

Вот «традиционное» решение, которое использует синтаксис косвенности !. Это все еще немного хрупкая, но не так плохо, как eval:

select array in "FIRST" "SECOND" "THIRD" "FOURTH" "FIFTH" "SIXTH" "SEVENTH"; do 
    if [[ $array ]]; then 
    # Indirection requires the full subscript to be included 
    # in the variable which is used to indirect. "${!array[@]}" 
    # would be "0", because that is not indirect syntax; rather it 
    # is "array keys" syntax. 
    array_at="$array"[@] 
    echo "${!array_at}" 
    break 
    else 
    echo "Invalid input; try again" >> /dev/stderr 
    fi 
done 

С Баш 4,3, вы можете использовать справочные объявления, которые делают выше немного меньше неуклюжим:

select name in "FIRST" "SECOND" "THIRD" "FOURTH" "FIFTH" "SIXTH" "SEVENTH"; do 
    if [[ $name ]]; then 
    declare -n array=name 
    echo "${array[@]}" 
    break 
    else 
    echo "Invalid input; try again" >> /dev/stderr 
    fi 
done 
# Unless the user exits the select by typing an EOF, 
# then `array` is now effectively a synonym 
# for whichever of the arrays was selected. 
+0

Удивительный ответ. Я понятия не имел об этом. Чем больше я узнаю о оболочке, тем больше я могу оценить ее гибкость и находчивость. – user148854

+0

Я получаю сообщение об ошибке: строка 5: объявить: -n: неверный параметр – kuruvi

+0

@kuruvi: проверьте свою версию bash. – rici

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

  • Нет связанных вопросов^_^