2

渡された変数の名前をbashで理解する方法はありますか?

例:

var1=file1.txt
err_var=errorfile.txt

function func1 {
   echo "func1: name of the variable is: " $1
   echo "func1: value of variable is: " $1 
   echo
   if [ ! -e $var1 ]
   then
      $1 = $err_val  #is this even possible?
   fi
   func2 $1
}

function func2 {
   echo "func2: name of the variable is: " $1
   echo "func2: value of variable is: " $1 
   echo
}

func1 $var1
func1 $err_var

file1.txtが存在する場合、次の出力が得られることを期待していました。

func1: name of the variable is: var1
func1: value of variable is: file1.txt

func2: name of the variable is: var1
func2: value of variable is: file1.txt

また、file1.txtが存在しない場合:

func1: name of the variable is: var1
func1: value of variable is: file1.txt

func2: name of the variable is: err_var
func2: value of variable is: errorfile.txt

何か案は?

4

2 に答える 2

11

いいえ、変数は関数が認識する前に展開されます。関数は値のみを認識し、変数名は認識しません。

変数名を展開せずにドル記号なしで渡す場合は、間接参照を使用できます。

get_it () {
    echo "${!1}"
}

デモ:

$ foo=bar
$ baz=qux
$ get_it foo
bar
$ get_it baz
qux
于 2012-06-08T20:19:24.550 に答える
0

デニスが言ったように、ドル記号を使用して変数を展開すると、関数には変数名を取得する方法がなくなります。しかし、変数の値を設定する方法についても質問されたと思いますが、その部分はまだ回答されていません。declare -n(興味があればグーグル)のように、それを行うためのいくつかの移植性のない方法がありますが、私の答えは普遍的な解決策に固執するつもりです。

私はC++プログラマーなので、変数の値を取得および設定するために小さな関数を使用する「ゲッターとセッター」の哲学を模倣するのが好きです。ゲッターとセッターを使用することの欠点は、管理するすべての値に対して1つ(または2つの関数)を作成する必要があることです。だから...私はあなたのためにゲッター/セッターの作成を処理する「ファクトリー関数」を作成しました:

makeGetSet() {
. /dev/fd/0 <<END_FUNC
${1}Val()  { [ "\${1}" ] && ${1}="\${1}" || echo "\${${1}}"; }
END_FUNC
}

namerefs間接参照や、、またはdeclareユーティリティなどの特別な機能を備えた特定のシェルは必要ありません。いいえeval、いいえ、 alias100%POSIXです。変数名をに渡すだけでmakeGetSet、getter / setter関数の名前は同じValで、末尾に「」が付きます(例myVariableVal)。bashおよびでテスト済みdash。私の関数と組み合わせて、変数の読み取り/書き込みに「通常の」シェルの方法を引き続き使用できます。

使用法:

Setup: makeGetSet myVariable
Set: myVariableVal newValue
Get: anotherVariable="`myVariableVal`"
Print: myVariableVal

スクリプトのいくつかの部分についてはよくわかりませんでしたので、知識に基づいて推測しました。あなたが持っているところif [ ! -e $var1 ]、私はあなたが意味したと思いますif [ ! -e $1 ]。そして最後に、関数を呼び出すところにとがfunc1 $var1ありましたが、3番目の変数を使用するか持つfunc1 $err_varつもりだったと思います。func1 $var1入力として与えるものではなく、「エラーのデフォルト値」のように見え$err_varますが、おそらく私はあなたの考えに従わないでしょう。

したがって、あなたの質問に対する私の答えは次のようになります。

var1=file1.txt; makeGetSet var1
err_var=errorfile.txt; makeGetSet err_var

function func1 {
   echo "func1: name of the variable is: " ${1%Val}
   echo "func1: value of variable is: " `${1}`
   echo
   # Shorter than if..fi
   [ ! -e `${1}` ] && ${1} ${err_val}
   func2 ${1}
}

function func2 {
   echo "func2: name of the variable is: " ${1%Val}
   echo "func2: value of variable is: " `${1}` 
   echo
}

func1 ${var1}
于 2021-05-18T09:04:59.007 に答える