bash – использовать значение переменной int для ссылки на параметр позиции в функции

Я хотел бы использовать переменную say:

i=1 

как значение для ссылки на позиционные переменные, переданные скрипту, например:

 x=101 y=201 z=301 foo(){ echo "$1" echo "$2" echo "$3" } foo xyz 

вывод:

 101 201 301 

Вместо того, чтобы ссылаться на каждый параметр по индексу, как я могу использовать i для увеличения в качестве индексной переменной?

Чтобы уточнить:

 foo() { local i=1 echo "$i" #echo first paramter (( i+=1 )) echo "$i" #echo second parameter #etc. } 

Каков синтаксис части echo "$i" ?

ОБНОВЛЕНИЕ после ответа @Eric

 ~$ t=5 ~$ foo() { i=1; echo "${!i}"; } ~$ foo t t ~$ 

Обновление # 2

Короче говоря, единственный способ заставить мой метод работать:

 foo() { #assuming 3 parameters i=0 (( i+=1 )) var="${!i}" echo "${!var}" (( i+=1 )) var="${!i}" echo "${!var}" (( i+=1 )) var="${!i}" echo "${!var}" } 

  • Ручная настройка переменных среды для Metasploit
  • Вход в систему с конкретной оболочкой при входе в терминал
  • Каковы режимы readline, раскладки клавиш и их привязки по умолчанию?
  • рыба: пробел в псевдониме
  • Как выбрать второй столбец после найденного шаблона, шаблоны - «100»,
  • Как искать и извлекать строку из вывода команды?
  • скрипт для сравнения двух строк "foo" и "bar"
  • Эффективное объединение / сортировка / уникальное большое количество текстовых файлов
  • 2 Solutions collect form web for “bash – использовать значение переменной int для ссылки на параметр позиции в функции”

    Это похоже на вопрос SO здесь , который похож на комментарий @costas. Вы можете использовать $# чтобы получить количество аргументов, а затем косвенные ссылки, такие как ${!i} для доступа к переменной по имени. Вот пример:

     f() { for((i=1; i<=$#; i++)); do printf "%d %s\n" "$i" "${!i}" done } fabc 

    который печатает:

     1 a 2 b 3 c 

    Увидев теперь, что вы хотите передать имена переменных в качестве позиционных аргументов, вы можете добавить дополнительный слой косвенной ссылки так:

     a=first b=second c=third f() { for((i=1; i<=$#; i++)); do var="${!i}" printf "%d %s\n" "$i" "${!var}" done } fabc 

    который печатает

     1 first 2 second 3 third 

    Это позволяет рассматривать каждый аргумент как имя переменной, которую мы храним в var здесь. Затем мы косвенно printf этой переменной в printf .

    Вы получаете только один слой косвенности за раз, вложенность не работает. Поэтому попытка сделать это одним махом, поскольку ${!${!i}} не работает, потому что первый { запускает разложение, а остальное рассматривается как значение PARAMETER для расширения. Первый персонаж ! он будет рассматривать остальное как имя ПАРАМЕТРА, содержащее имя требуемого параметра, но ${!i} не является допустимым именем параметра, поэтому мы получаем bad substitution . Поэтому мы просто делаем это за 2 шага, чтобы избежать этой проблемы.

    Используя shift , вы можете сделать следующее:

     num_args="$#" for (( i = 1; i <= "$num_args"; i++ )); do echo "$1" shift done 

    Здесь команда shift сдвигает каждый следующий аргумент из аргументов, переданных скрипту, на значение $1 .

    Например:

     $ ./myscript one two three four five six one two three four five six 

    в результате чего при первом запуске цикла, $1 = "one" , затем во втором запуске цикла, $1 = "two" и т. д. до последнего аргумента.


    Изменить: если вы хотите получить доступ к любому из ваших аргументов сценария без заказа, например. используя 2-й и 4-й аргументы, один метод использует массивы bash следующим образом:

     # Initialize the array 'myargs' with all script arguments myargs=( "$@" ) for (( i = 0; i < "$#"; i++ )); do echo "${myargs[$i]}" done 

    Здесь вы можете получить доступ к любому из ваших аргументов с любым указанным индексом i используя форму "${myargs[$i]}" .

    Linux и Unix - лучшая ОС в мире.