Bashはバージョン4.3以降、2014年2月(?)で、「eval」を超える参照変数または名前参照(namerefs)を明示的にサポートしており、同じ有益なパフォーマンスと間接効果を備えています。 「 'eval'を忘れてこのエラーを修正する必要がある」:
declare [-aAfFgilnrtux] [-p] [name[=value] ...]
typeset [-aAfFgilnrtux] [-p] [name[=value] ...]
Declare variables and/or give them attributes
...
-n Give each name the nameref attribute, making it a name reference
to another variable. That other variable is defined by the value
of name. All references and assignments to name, except for⋅
changing the -n attribute itself, are performed on the variable
referenced by name's value. The -n attribute cannot be applied to
array variables.
...
When used in a function, declare and typeset make each name local,
as with the local command, unless the -g option is supplied...
そしてまた:
パラメーター
変数にnameref属性を割り当てて、-nオプションをdeclareまたはlocal組み込みコマンド(declareおよびlocalの説明を参照)に割り当てて、namerefまたは別の変数への参照を作成できます。これにより、変数を間接的に操作できます。nameref変数が参照または割り当てられるたびに、nameref変数の値で指定された変数に対して実際に操作が実行されます。namerefは通常、関数に引数として渡される名前を持つ変数を参照するためにシェル関数内で使用されます。たとえば、変数名が最初の引数としてシェル関数に渡された場合、
declare -n ref=$1
関数内で、値が最初の引数として渡された変数名であるnameref変数refを作成します。refへの参照と代入は、名前が$ 1として渡された変数への参照と代入として扱われます。forループの制御変数にnameref属性がある場合、単語のリストはシェル変数のリストにすることができ、ループが実行されると、リスト内の各単語に対して名前参照が確立されます。配列変数に-n属性を指定することはできません。ただし、nameref変数は配列変数および添え字付き配列変数を参照できます。組み込みのunsetに-nオプションを使用すると、名前参照を設定解除できます。それ以外の場合、nameref変数の名前を引数としてunsetを実行すると、
たとえば(EDIT 2:(ありがとう、ロン)名前空間付き(接頭辞付き)の関数内部変数名。外部変数の衝突を最小限に抑えるために、最終的に適切に応答する必要があります。Karstenのコメントで指摘された問題):
# $1 : string; your variable to contain the return value
function return_a_string () {
declare -n ret=$1
local MYLIB_return_a_string_message="The date is "
MYLIB_return_a_string_message+=$(date)
ret=$MYLIB_return_a_string_message
}
この例をテストします:
$ return_a_string result; echo $result
The date is 20160817
組み込みのbash "declare"を関数で使用すると、宣言された変数がデフォルトで "local"になり、 "-n"も "local"と共に使用できることに注意してください。
「重要な宣言」変数と「退屈なローカル」変数を区別したいので、このように「宣言」と「ローカル」を使用すると、ドキュメントとして機能します。
編集1-(カルステンによる以下のコメントへの応答)-もうコメントを追加することはできませんが、カルステンのコメントは私に考えさせられたので、私はWORKS FINE、AFAICT-カルステンをテストしましたこれを読んだら、正確なセットを提供してください次のステップは問題なく機能するため、コマンドラインからテストステップを実行して、存在すると想定される問題を示します。
$ return_a_string ret; echo $ret
The date is 20170104
(上記の関数をbashの項に貼り付けた直後にこれを実行しました-ご覧のとおり、結果は正常に機能します。)
function funcName {
POSIX以前のレガシー構文は初期のkshから継承されたものです(bashが尊重しない意味上の違いがあったため)。funcName() {
なしでfunction
、代わりに使用する必要があります。wiki.bash-hackers.org/scripting/obsoleteを