简体   繁体   English

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

[英]Name of variable passed to function in bash

Is there a way in bash to understand the name of a variable that's passed to it? bash 中有没有办法理解传递给它的变量的名称?

Example:例子:

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

I was hoping to get the following output if file1.txt exists:如果 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

And when file1.txt does not exist:当 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

Any ideas?有任何想法吗?

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

Like Dennis said, once you've expanded the variable using the dollar-sign, your function no longer has a way to get the variable name.就像丹尼斯说的那样,一旦你使用美元符号扩展了变量,你的函数就不再有办法获取变量名了。 But I think you also asked about a way to set the variable's value, and that part hasn't been answered yet.但是我认为您还询问了一种设置变量值的方法,而该部分尚未得到解答。 There are some non-portable ways to do that, like with declare -n (Google that if you're interested), but my answer is going to stick to a universal solution.有一些不可移植的方法可以做到这一点,例如declare -n (如果您感兴趣,请使用 Google),但我的答案将坚持通用解决方案。

I'm a C++ programmer, so I like to mimic the " getter and setter " philosophy, where you use tiny little functions to get and set the value of a variable.我是一名C++程序员,所以我喜欢模仿“ getter 和 setter ”的哲学,在那里你使用微小的函数来获取和设置变量的值。 The downside to using getters and setters is that you need to create a function (or two functions) for every value you want to manage.使用 getter 和 setter 的缺点是您需要为每个要管理的值创建一个函数(或两个函数)。 So... I made a "factory function" that handles creating getters/setters for you:所以......我做了一个“工厂函数”来为你创建 getter/setter:

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

It does not require any particular shell with special features like indirection or namerefs , or the declare utility.它不需要任何具有特殊功能的特定 shell,如间接或namerefsdeclare实用程序。 No eval , no alias es, just 100% POSIX.没有eval ,没有alias ,只有 100% POSIX。 You just pass in your variable name to makeGetSet , and your getter/setter function has that same name with a " Val " at the end (eg myVariableVal ).您只需将变量名称传递给makeGetSet ,并且您的 getter/setter 函数具有相同的名称,末尾带有“ Val ”(例如myVariableVal )。 Tested with bash and dash .bashdash测试。 You're free to continue using the "normal" shell ways to read/write to your variable in combination with my function.您可以继续使用“普通”shell 方式结合我的函数来读/写变量。

Usage:用法:

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

I wasn't sure about a couple parts of your script, so I took some educated guesses.我不确定你脚本的几个部分,所以我做了一些有根据的猜测。 Where you have if [ ! -e $var1 ] if [ ! -e $var1 ] if [ ! -e $var1 ] , I think you meant if [ ! -e $1 ] if [ ! -e $var1 ] ,我想你的意思是if [ ! -e $1 ] if [ ! -e $1 ] . if [ ! -e $1 ] And at the end, where you call the functions, you had func1 $var1 and func1 $err_var , but I think you meant to just use func1 $var1 or have a third variable.最后,在你调用函数的地方,你有func1 $var1func1 $err_var ,但我认为你打算只使用func1 $var1或有第三个变量。 It looks like $err_var is a "default value for errors" rather than something you'd give as input, but maybe I'm not following your idea.看起来$err_var是“错误的默认值”,而不是您作为输入提供的内容,但也许我没有遵循您的想法。

So my answer to your question would look like:所以我对你的问题的回答如下:

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}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM