在函数内部执行Bash间接变量赋值

5
我有一个脚本,需要多次评估用户输入。我的解决方案是将评估部分放入函数中,在每次需要评估输入时简单调用该函数。 然而问题是,当我尝试更新$1变量(它指的是函数的第一个参数变量)时,会得到"$VARIABLE命令未找到"的错误消息。
以下是代码:
function input_handler() {
 if is_integer $1; then
  selid="$1 -1"
  if [[ "$1" -le "0" ]]; then
   echo "Please use a simple positive number!"
  else
   if [[ "$1" -le "${#array[*]}" ]]; then
    eval $1="${array[selid]}"
    echo "Ok, moving on..."
   else
    echo "That number seems too large, try again?"
   fi
  fi
 else
  if [ -e $2/$1 ]; then
   echo "Ok, moving on..."
  else
   echo "That item is not on the list, try again!"
  fi
 fi
}

同时,这条命令:

input_handler $doctype $docpath

给出以下输出:
5
./test: line 38: 5=sun: command not found

好的,接着说...

现在这个几乎正确,但我需要的是 doctype=sun,而不是 5=sun,换句话说,我需要 $1 变量名而不是它的值。将行 eval $1="${array[selid]}" 改为 eval doctype="${array[selid]}" 可以解决这个特定的实例。但这并不能解决我的问题,因为我需要对不同名称的变量运行此函数。

4个回答

4
也许我不完全理解你想要实现什么,但请查看下面的示例:

也许不是很了解您想要实现的目标,但请参考以下示例:

weirdfunc () {
    echo " weirdfunc: variable name is: $1"
    echo " weirdfunc: variable value is: ${!1}"
    eval "$1=$(( ${!1} + 1))" #assign
}

myvar="5"
echo "the value of myvar before: $myvar"

weirdfunc myvar #call with the NAME not with the value, so NOT weridfunc $myvar

echo "the value of myvar after: $myvar"

简而言之,当你想在一个被调用的函数中对变量NAME进行任何操作时,应该传递变量的名称而不是它的值。因此,请调用该函数。
somefunc NAME

替代

somefunc $NAME

使用上述结构体在函数内获取名称和值。


也许我应该澄清一下我的意图。我正在处理的脚本输出一个文件条目列表并提示用户选择哪个文件,如果有效的话,它应该存储在变量$1中。到目前为止,一切都很顺利,但这里有个棘手的问题:为了使脚本更加用户友好,我在每个文件条目前面添加了数字。这样,用户可以键入相应的数字而不是完整的文件名。但是为了使其起作用,我需要将他的选择“如5”转换为有效的文件名“如sun”,并将其存储在$1变量中的函数。 - Dan-Simon Myrland
如果你想改变通过名称传递的变量的值,请使用上述结构。如果您想设置$1,请使用@kojiro的答案,但是说实话,我不明白为什么要这样做,当您可以使用任何辅助变量时......最好的方法是展示一个非常简短的例子——没有任何无关的“if”以及主要部分——不仅仅是函数本身...... - clt60
你说得完全正确!我通过添加一个辅助变量<code>helper="${array[selid]}"</code>来解决了这个问题,而不是使用<code>eval $1="${array[selid]}"</code>,并在函数外部调用它:<code>input_handler $doctype $docpath<br>doctype=$helper</code> 如果我表达不清楚,请原谅,我对stackoverflow和Bash脚本编写都比较新。感谢您的帮助! - Dan-Simon Myrland
@Dan-SimonMyrland:请在注释中使用反引号``像这样`来表示代码。 - Jonathan Leffler
@Dan-SimonMyrland 如果你需要在函数外修改一个变量,这个答案会告诉你如何正确地做到。 - novacik

0

您无法使用传统赋值方式更新$1的值,但是可以使用set内置函数来更新位置参数。

$ f() { echo "$@"; set -- a b c; echo "$@"; echo $2; }
$ f 1 2 3
1 2 3
a b c
b

请记住,这将清除您每次不重新设置的所有位置参数,因此如果您想保留它,则需要设置$2

最好的方法可能是将位置参数中的值分配给名称,然后从那时起只使用名称。


0

如果你保护变量名,Bash会将其评估并分配给$1,而不是尝试执行$1=value。

eval "$1"=${array[selid]}

-1

位置参数是只读的。所以你想做的事情是不可能的。你应该做类似这样的事情

foo=$1

然后使用$foo而不是$1进行操作


好的,但我仍然需要$1的名称而不是值,这可能吗? - Dan-Simon Myrland
1
位置参数不是只读的。您可以使用 set 更改它们。 - kojiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接