Em bash , você pode usar ${!varname} para expandir a variável referenciada pelo conteúdo de outra. Por exemplo:
$ var=hello
$ foo () { echo "${!1}"; }
$ foo var
hello
Da página do manual:
${!prefix*}
${!prefix@}
Names matching prefix. Expands to the names of variables whose names
begin with prefix, separated by the first character of the IFS special
variable. When @ is used and the expansion appears within double quotes,
each variable name expands to a separate word.
Além disso, para definir uma variável referenciada pelo conteúdo (sem os perigos de eval ), você pode usar declare . Por exemplo:
$ var=target
$ declare "$var=hello"
$ echo "$target"
hello
Assim, você poderia escrever sua função assim (tome cuidado, porque se você usa declare em uma função, você deve dar -g ou a variável será local):
shopt -s extglob
assign()
{
target=$1
bigstr=${!1}
substr=$2
if [ -z "$bigstr" ]; then
declare -g -- "$target=$substr"
elif [[ $bigstr != @(|*:)$substr@(|:*) ]]; then
declare -g -- "$target=$bigstr:$substr"
fi
}
E use-o como:
assign PATH /path/to/binaries
Note que eu também corrigi um erro onde se substr já é uma substring de um dos membros separados por dois pontos de bigstr , mas não seu próprio membro, então não seria adicionado. Por exemplo, isso permitiria a adição de /bin a uma variável PATH contendo /usr/bin . Ele usa os conjuntos extglob para corresponder ao início / fim da sequência ou dois-pontos e depois a qualquer outra coisa. Sem extglob , a alternativa seria:
[[ $bigstr != $substr && $bigstr != *:$substr &&
$bigstr != $substr:* && $bigstr != *:$substr:* ]]