バッシュ4を使用しています。
Bashでいくつかの実験をしようとしています。変数の値に配列を動的に割り当てたいです。以下のコードを読んでみると、理解しやすくなります。
myFunc =RESULT_PREF 'bar' 'baz'
function myFunc() {
local params
parser params "$@"
}
function parser() {
if [ '=' = "${2::1}" ]; then
local name="${1}"
shift 2
local param_array=( "$@" )
# In PHP, I'd do:
# $$name = $param_array
# The ideal outcome:
# $params should contain the values 'bar' and 'baz'.
fi
}
コードコメントで言及した内容をどのように実行できますか?これを行うためにevalを使用できないようです。可能であっても評価に関する悪い内容をたくさん読んだ。
どんな提案がありますか?
ベストアンサー1
Bash 4.3+には変数参照を定義する方法があります。以下で確認できますhelp declare
。
-N:NAME を値の名前付き変数への参照にします。
したがって、このようなスクリプトは1行を出力しますa
。
n(){ declare -n g="$1"; g=a; }
n b; printf '%s\n' "$b";
だからあなたはこれをしなければなりませんparser
:
parser() {
[ "$1" ] || ! echo 'no name given' >&2 || return 42
if [[ "$2" == =* ]]; then
declare -n name="$1"
shift 2
name=("$@")
fi
}
以下を使用するとeval
機能しますが、rhsが早すぎると安全ではない可能性があります。
shopt -e extglob # bash >= 3
[[ "$1" == [[:alpha:]_]*([[:word:]]) ]] || return 42 # invalid varname
# mikeserv has another solution for filtering, basically expanding
# the inverse of the expression to basic, portable globs
# Do this:
eval "$1"'=( "$@" )'
eval "$foo=\$bar"
# But not:
eval "$1=(\"$@\")"
eval "$foo=$bar"
それでは、何をすべきかを知ることができると思いますeval
。しかし、あなたが私の答えを受け入れる可能性をさらに高めるために完全な内容を書いてみましょう。
shopt -s extglob
parser() {
[[ "$1" == [[:alpha:]_]*([[:word:]]) ]] || ! echo 'bad varname' >&2 || return 42
if [[ "$2" == =* ]]; then
name="$1"
shift 2
eval "$name=(\"\$@\")"
fi
}