如何更新BASH中另一个变量内的变量?

时间:2014-10-30 06:20:02

标签: bash

我有一个变量$var_c,其中包含许多复杂的语法。我宁愿不需要多次重写,因为很容易犯错误。但有时数据会发生变化。

#!/bin/bash

var_a="cat"
var_b="dog"

var_c="<div class=\"pet_a\">$var_a</div><div class=\"pet_b\">$var_b</div>"

echo $var_c

var_a="fish"
var_b="whale"

echo $var_c

这应首先<div class="pet_a">cat</div><div class="peg_b">dog</div>然后<div class="pet_a">fish</div><div class="peg_b">whale</div>,但是,在更改变量$var_a$var_b后,$var_c不会更新。

如何告诉BASH更新此变量,而不必再次完全提供所有语法?

3 个答案:

答案 0 :(得分:5)

使用Shell函数

在Bash中,赋值中的插值在赋值时发生 。所以,你真的可以做你正在尝试用变量做的事情。相反,您应该使用shell函数。例如:

var_a="cat"
var_b="dog"
var_c () {
    echo "<div class=\"pet_a\">$var_a</div><div class=\"pet_b\">$var_b</div>"
}
echo $(var_c)
# <div class="pet_a">cat</div><div class="pet_b">dog</div>

var_a="fish"
var_b="whale"
echo $(var_c)
# <div class="pet_a">fish</div><div class="pet_b">whale</div>

请注意,在这种情况下,您可以直接调用var_c,而不是echo $(var_c),因为该函数已包含echo语句。我故意在示例中使用它来维护当前的语义,并展示如何使用像变量这样的shell函数。

答案 1 :(得分:3)

使用Printf格式字符串

在Bash中,赋值中的插值发生在赋值时。所以,你真的可以做你正在尝试用变量做的事情。解决此问题的一种方法是使用格式字符串和内置的 printf 。内置程序支持-v标志,其中包含:

  -v var    assign the output to shell variable VAR rather than
            display it on the standard output

例如:

fmt="<div class=\"pet_a\">%s</div><div class=\"pet_b\">%s</div>"
var_a="cat"
var_b="dog"
printf -v var_c "$fmt" "$var_a" "$var_b"
echo "$var_c"
# <div class="pet_a">cat</div><div class="pet_b">dog</div>

var_a="fish"
var_b="whale"
printf -v var_c "$fmt" "$var_a" "$var_b"
echo "$var_c"
# <div class="pet_a">fish</div><div class="pet_b">whale</div>

答案 2 :(得分:1)

变量包含数据,而不是逻辑。设置变量时,您将其设置为特定值,而不是计算该值的规则。如果你想要在不同时间返回不同结果的东西,你需要更像功能的东西:

func_c() {
    echo "<div class=\"pet_a\">$var_a</div><div class=\"pet_b\">$var_b</div>"
}

var_a="cat"
var_b="dog"
echo "$(func_c)"  # echoes '<div class="pet_a">cat</div><div class="pet_b">dog</div>'

var_a="fish"
var_b="whale"
echo "$(func_c)"  # echoes '<div class="pet_a">fish</div><div class="pet_b">whale</div>'

请注意,执行函数时使用语法$(functionname)(这实际上可以与任何命令一起使用),而不仅仅是$variablename用于变量。此外,您几乎总是将函数和变量引用都放在双引号中(如上所述)。另外,如果您只是打印结果,请不要像我上面那样使用echo "$(functionname)",只需直接使用functionname即可。最后,使函数依赖于全局变量(var_a和var_b)通常是不好的做法 - 它们应该接收它们将作为参数操作的数据:

func_c() {
    # Usage: func_c var_a var_b
    echo "<div class=\"pet_a\">$1</div><div class=\"pet_b\">$2</div>"
}

func_c "cat" "dog"  # echoes '<div class="pet_a">cat</div><div class="pet_b">dog</div>'
func_c "fish" "whale"  # echoes '<div class="pet_a">fish</div><div class="pet_b">whale</div>'
var_d="$(func_c "ferret" "weasel")"  # sets var_d to '<div class="pet_a">ferret</div><div class="pet_b">weasel</div>'

(我使用的双引号多于上面例子中的严格要求 - 但最好在不需要时使用它们,而不是在需要时将它们关闭。)