在bash中传递给函数的变量的名称

时间:2012-06-08 20:10:16

标签: linux bash

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

有什么想法吗?

2 个答案:

答案 0 :(得分:11)

不,变量在函数看到之前展开。该函数只能看到值,而不是变量名。

如果您传递的变量名称未扩展且没有美元符号,则可以使用间接。

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

演示:

$ foo=bar
$ baz=qux
$ get_it foo
bar
$ get_it baz
qux

答案 1 :(得分:0)

就像丹尼斯说的,一旦你使用美元符号扩展了变量,你的函数就不再有办法获取变量名了。但是我认为您还询问了一种设置变量值的方法,而该部分尚未得到解答。有一些不可移植的方法可以做到这一点,例如 declare -n(如果您感兴趣,可以使用 Google),但我的答案将坚持通用解决方案。

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

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

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

用法:

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

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