我正在尝试通过使用函数来整理我的一个bash脚本。该脚本从config.ini文件中设置许多变量,然后列出它们并要求确认用户希望继续使用这些预定义值。如果没有,它会逐步执行每个变量并要求输入一个新变量(或将其留空并按Enter键以使用预定义值)。这段代码实现了:
echo Current output folder: $OUTPUT_FOLDER
echo -n "Enter new output folder: "
read C_OUTPUT_FOLDER
if [ -n "$C_OUTPUT_FOLDER" ]; then OUTPUT_FOLDER=$C_OUTPUT_FOLDER; fi
我们的想法是将$OUTPUT_FOLDER
设置为$C_OUTPUT_FOLDER
的值,但前提是$C_OUTPUT_FOLDER
不为空。如果$C_OUTPUT_FOLDER
为空,则它将不执行任何操作,并保留$OUTPUT_FOLDER
,以便稍后在脚本中使用。
config.ini中设置了6个变量,因此该块当前重复了6次。我已经创建了一个函数new_config ()
,如下所示:
new_config () {
echo Current $1: ${!2}
echo -n "Enter new $1: "
read $3
if [ -n "${!3}" ]; then $2=${!3}; fi
}
我正在调用它(在这个例子中):
new_config "output folder" OUTPUT_FOLDER C_OUTPUT_FOLDER
当我运行脚本时,它在if
行上有错误:
./test.sh: line 9: OUTPUT_FOLDER=blah: command not found
那么,是什么给出的?脚本中的代码块运行良好(在我非常新的眼中),函数应该完全相同。
提前感谢任何指示。
答案 0 :(得分:0)
问题是bash在变量替换之前将命令拆分为标记,请参阅http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_01_04.html#sect_01_04_01_01。具体来说,POSIX shell的规则使赋值成为标记化的特殊情况:"If all the characters preceding '=' form a valid name (see XBD Name), the token ASSIGNMENT_WORD shall be returned." - 它是触发赋值路径的ASSIGNMENT_WORD标记。它不会在变量替换后重复标记化,这就是您的代码不起作用的原因。
您可以让代码像这样工作:
new_config () {
echo Current $1: ${!2}
echo -n "Enter new $1: "
read $3
if [[ -n "${!3}" ]]; then echo setting "$2='${!3}'"; eval "$2='${!3}'"; fi
}
new_config "output folder" OUTPUT_FOLDER C_OUTPUT_FOLDER
echo $OUTPUT_FOLDER
正如@chepner指出的那样,你可以在这里使用declare -g $2="${!3}"
而不是eval,在更新的bash版本上使用更好的答案。不幸的是declare -g
需要bash 4.2,即使它已经3年了,它仍然不是无处不在 - 例如,OS X Mavericks仍然停留在3.2.51。