Bash函数参数未按预期传递

时间:2015-10-28 17:18:27

标签: bash function arguments

我的脚本中有一个意外的行为:

#!/bin/bash
checkFolders "first folder"

checkFolders() {
    checkEmptyVar $1 "folder to be copied"
}

checkEmptyVar() {
    echo "0: $0  1: $1   2: $2"
    [[ $(isNotEmpty $1) = false ]] && (echo "Specify a path for $2") && exit
    echo "post exit"
}

函数checkEmptyVar回应以下内容:

0: ./lcp.sh  1: folder to be copied   2: 

我原本希望将“要复制的文件夹”作为$1的{​​{1}}传递,会发生什么事?

2 个答案:

答案 0 :(得分:3)

你有很多问题:

  1. $0不是函数的第一个参数; $1是。 $0是当前脚本的名称。
  2. 您必须引用参数扩展,以防止它们在嵌入的空格中被拆分为多个单词。
  3. 必须在使用之前定义函数。
  4. 正确的脚本是

    #!/bin/bash
    
    
    checkFolders() {
        checkEmptyVar "$1" "folder to be copied"
    }
    
    checkEmptyVar() {
        [[ $(isNotEmpty "$1") = false ]] && echo "Specify a path for $2" && exit
        echo "post exit"
    }
    
    checkFolders "first folder"
    

    此外,让isNotEmpty返回非零值而不是输出字符串false会更好,这样就可以编写

    checkEmptyVar () {
        if isNotEmpty "$1"; then
            echo "Specify a path for $2" >&2   # Use standard error, not standard output
            exit 1
        fi
        echo "post exit"
    }
    

    (我怀疑你无论如何都可以用isNotEmpty替换[[ -n $1 ]]。)

答案 1 :(得分:1)

这个脚本不是你想象的那样。你的函数定义发生得太晚了。

当您在第一行调用checkFolders时,您将从预先存在的环境调用该函数的版本,而不是稍后在该脚本中定义的版本。

如果你从shell运行command -V checkFolders,那么我希望你输出的输出有点像:

checkFolders is a function
checkFolder ()
{
    checkEmptyVar "folder to be copied"
}

虽然有可能在那里。

当你使用变量来阻止shell对其内容进行分词时,你也应该总是引用变量。

当您致电checkFolders "first folder"并最终致电checkFolders first folder "folder to be copied"并且根本不是您想要的时间时,请不要这样做。

反转您的功能和通话顺序并修复您的变量报价,您应该看到您的期望。