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
有什么想法吗?
答案 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
,没有 alias
es,只有 100% POSIX。您只需将变量名称传递给 makeGetSet
,您的 getter/setter 函数具有相同的名称,末尾带有“Val
”(例如 myVariableVal
)。使用 bash
和 dash
进行测试。您可以继续使用“普通”shell 方式结合我的函数来读/写变量。
用法:
Setup: makeGetSet myVariable
Set: myVariableVal newValue
Get: anotherVariable="`myVariableVal`"
Print: myVariableVal
我不确定你脚本的几个部分,所以我做了一些有根据的猜测。如果你有 if [ ! -e $var1 ]
,我想你的意思是 if [ ! -e $1 ]
。最后,在你调用函数的地方,你有 func1 $var1
和 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}