Имена динамических переменных в Bash
Я смущен сценарием bash.
у меня есть следующий код:
function grep_search() {
magic_way_to_define_magic_variable_=`ls | tail -1`
echo $magic_variable_
}
Я хочу иметь возможность создать имя переменной, содержащее первый аргумент команды и несущее значение, например, последней строки ls
.
Итак, чтобы проиллюстрировать, что я хочу:
$ ls | tail -1
stack-overflow.txt
$ grep_search() open_box
stack-overflow.txt
Итак, как я должен определить/объявление $magic_way_to_define_magic_variable_
и как я должен назвать это в сценарии?
Я пробовал eval
, ${...}
, $${...}
, но я все еще смущенный.
9 ответов
используйте ассоциативный массив с именами команд в качестве ключей.
# Requires bash 4, though
declare -A magic_variable=()
function grep_search() {
magic_variable[]=$( ls | tail -1 )
echo ${magic_variable[]}
}
если вы не можете использовать ассоциативные массивы (например, необходимо поддерживать bash
3), Вы можете использовать declare
для создания имен динамических переменных:
declare "magic_variable_=$(ls | tail -1)"
и используйте косвенное расширение параметра для доступа к значению.
var="magic_variable_"
echo "${!var}"
См. BashFAQ:Indirection-оценка косвенных / ссылочных переменных.
Я искал лучший способ сделать это в последнее время. Ассоциативный массив казался мне излишним. Посмотрите, что я нашел:
suffix=bzz
declare prefix_$suffix=mystr
...и...
varname=prefix_$suffix
echo ${!varname}
Это должно работать:
function grep_search() {
declare magic_variable_="$(ls | tail -1)"
echo "$(tmpvar=magic_variable_ && echo ${!tmpvar})"
}
grep_search var # calling grep_search with argument "var"
для индексированных массивов, вы можете ссылаться на них, как так:
foo=(a b c)
bar=(d e f)
for arr_var in 'foo' 'bar'; do
declare -a 'arr=("${'"$arr_var"'[@]}")'
# do something with $arr
echo "$$arr_var contains:"
for char in "${arr[@]}"; do
echo "$char"
done
done
ассоциативные массивы могут ссылаться аналогично, но нуждаются в -A
переключатель declare
вместо -a
.
Вау, большая часть синтаксиса ужасна! Вот одно решение с более простым синтаксисом, если вам нужно косвенно ссылаться на массивы:
#!/bin/bash
foo_1=("fff" "ddd") ;
foo_2=("ggg" "ccc") ;
for i in 1 2 ;
do
eval mine=( ${foo_$i[@]} ) ;
echo ${mine[@]} ;
done ;
для более простых случаев я рекомендую использовать тег синтаксис, описанный в Расширенный Bash-Руководство Сценариев.
Я хочу иметь возможность создать имя переменной, содержащее первый аргумент команды
:
#!/usr/bin/env bash
function grep_search() {
eval =$(ls | tail -1)
}
по состоянию на BashFAQ/006, вы можете использовать read
С здесь синтаксис строки для распределения косвенных переменных:
function grep_search() {
read "" <<<$(ls | tail -1);
}
использование:
$ grep_search open_box
$ echo $open_box
stack-overflow.txt