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

No, the variable is expanded before the function sees it. The function only sees the value, not the variable name.

If you pass the variable name unexpanded and without the dollar sign, you can use indirection.

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

Demo:

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

就像丹尼斯所说,一旦你使用美元符号扩展了变量,你的函数就不再有办法获取变量名。但是我认为您还询问了一种设置变量值的方法,而那部分还没有得到回答。有一些非便携式的方法可以做到这一点,比如declare -n(如果你感兴趣的话,谷歌),但我的回答是坚持一个通用的解决方案。

我是一名C++程序员,所以我喜欢模仿“ getter and setter ”哲学,在这种哲学中,您可以使用微小的函数来获取和设置变量的值。使用 getter 和 setter 的缺点是您需要为要管理的每个值创建一个函数(或两个函数)。所以......我做了一个“工厂函数”来为你处理创建getter/setter:

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

它不需要任何具有特殊功能的特定外壳,例如间接或namerefs实用declare程序。不eval,不alias,只有 100% POSIX。您只需将变量名称传递给,您的 getter/setter 函数具有相同的名称,并在末尾makeGetSet带有“ ”(例如)。用和测试。您可以结合我的函数继续使用“普通”shell 方式来读取/写入变量。ValmyVariableValbashdash

用法:

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

我不确定你剧本的几个部分,所以我做了一些有根据的猜测。你在哪里if [ ! -e $var1 ],我想你的意思是if [ ! -e $1 ]。最后,在你调用函数的地方,你有func1 $var1and 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 回答