Bash 函数内的参数替换

Bash 函数内的参数替换,bash,shell,Bash,Shell,当用户点击enter inread validate() { local validated=false while [ "$validated" != "true" ]; do read -p "$1 " $2 $2=${2:-y} if [[ "$2" == "y" || "$2" == "n" ]]; then validated=true

当用户点击enter in
read

validate() {
    local validated=false
    while [ "$validated" != "true" ]; do
            read -p "$1 " $2
            $2=${2:-y}
            if [[ "$2" == "y" || "$2" == "n" ]]; then
                    validated=true
            fi
    done
}
当我使用
validate“text”test
运行此函数并使用enter跳过
read
时,会出现错误
test=test:command not found

如何使用函数参数替换?

要将值写入具有动态名称的变量,可以使用
printf-v“$name”“$value”
。 这应该更接近你想要的, 尽管我怀疑还有一些进一步的困惑和后续问题:

validate() {
    local message=$1
    local out=$2
    local validated=false answer

    while [ "$validated" != true ]; do
        read -p "$message " answer
        answer=${answer:-y}
        if [[ "$answer" == "y" || "$answer" == "n" ]]; then
            validated=true
        fi
    done

    printf -v "$out" "$answer"
}

有几个问题,但你可以通过你的陈述最容易看出

$2=${2:-y}
假设用户将字符串FOO作为第二个参数传递。这句话变成

FOO=FOO
当然不是你所期望的。现在假设没有第二个参数被传递。在本例中,
$2
计算为空字符串,
$2=${2:-y}
计算为y。因此,这句话就变成了

=y
这在语法上甚至是不正确的。考虑到这一点,您可以看到

read -p "$1 " $2
也没有道理


编写函数时,最好的方法是不要在算法本身中使用位置参数(除非您有充分的理由这样做),而是将它们分配给变量,并始终如一地使用变量,正如@janos在其建议的解决方案中所示。它不仅更安全,而且使您的程序更容易理解。

请解释为什么要在
read-p“$1”$2
中使用
$2
validate
函数中第二个参数的用途是什么?$2是一个传递的变量,我想稍后与新值
read
一起使用。
read
的参数是要设置的变量的名称;该名称可以硬编码或由任意表达式提供
read-p“$1”“$2”
工作正常,但随后需要使用间接参数展开来检查结果,因此通过使用硬编码名称简化函数的其余部分,直到您准备好设置最终值为止。