在Bash 4.0.0中解决$@未绑定变量的问题?

在Bash 4.0.0中解决$@未绑定变量的问题?,bash,shell,sh,bash4,Bash,Shell,Sh,Bash4,特别是在Bash版本4.0.0中,当启用set-u时,是否有任何方法可以避免使用空$@引发未绑定变量错误 考虑以下几点: #!/usr/bin/env bash-4.0.0-1 set -xvu echo "$BASH_VERSION" echo "${BASH_VERSINFO[@]}" main () { printf '%q\n' "${@:-}" } main "${@:-}" 当我提供一组空参数时,提供以下输出: neech@nicolaw.uk:~ $ ./test.s

特别是在Bash版本4.0.0中,当启用set-u时,是否有任何方法可以避免使用空$@引发未绑定变量错误

考虑以下几点:

#!/usr/bin/env bash-4.0.0-1

set -xvu

echo "$BASH_VERSION"
echo "${BASH_VERSINFO[@]}"

main () {
  printf '%q\n' "${@:-}"
}

main "${@:-}"
当我提供一组空参数时,提供以下输出:

neech@nicolaw.uk:~ $ ./test.sh

echo "$BASH_VERSION"
+ echo '4.0.0(1)-release'
4.0.0(1)-release
echo "${BASH_VERSINFO[@]}"
+ echo 4 0 0 1 release x86_64-unknown-linux-gnu
4 0 0 1 release x86_64-unknown-linux-gnu

main () {
  printf '%q\n' "${@:-}"
}

main "${@:-}"
./test.sh: line 12: $@: unbound variable
我只在Bash版本4.0.0中看到这种行为

我希望使用变量替换${@:-}可以解决这个问题,但似乎不行

有办法解决这个问题吗?

$@,$*是特殊变量,所以应该始终定义它是一个bug

一个解决办法,也许是:

set +u
args=("$@")
set -u

main "${args[@]}"
或者也可能

main "${@:+$@}"
$@,$*是特殊变量,因此应始终定义它是一个bug

一个解决办法,也许是:

set +u
args=("$@")
set -u

main "${args[@]}"
或者也可能

main "${@:+$@}"

为什么不自己处理错误呢?通过这种方式,您可以准确地控制遇到异常时发生的情况,例如,返回该错误的自定义退出代码和消息,而不是局限于某些预定义的行为

function log_error                                                          
{                                                                           
    [[ $# -ne 1 ]] && return 1                                              

    typeset msg="$1"                                                        
    typeset timestamp=$(date "+%F %T")                                      

    echo "[${timestamp}] [ERROR] - $msg " >&2                               
}

if [[ -z "$BASH_VERSION" ]]                                                 
then                                                                        
    log_error "BASH VERSION is not set"                                     
    exit 1                                                                  
fi 

为什么不自己处理错误呢?通过这种方式,您可以准确地控制遇到异常时发生的情况,例如,返回该错误的自定义退出代码和消息,而不是局限于某些预定义的行为

function log_error                                                          
{                                                                           
    [[ $# -ne 1 ]] && return 1                                              

    typeset msg="$1"                                                        
    typeset timestamp=$(date "+%F %T")                                      

    echo "[${timestamp}] [ERROR] - $msg " >&2                               
}

if [[ -z "$BASH_VERSION" ]]                                                 
then                                                                        
    log_error "BASH VERSION is not set"                                     
    exit 1                                                                  
fi 

您有什么重要的理由不简单地升级到较新版本的bash吗?4.0.0在这一点上已经超过8年,并且有四个版本已经过时;如果不是因为macOS坚持使用3.2的特殊情况,我想任何人都会毫不犹豫地建议至少使用4.2,如果不是4.3的话。另一个解决办法是在脚本经过合理调试后关闭set-u。如果您担心变量由于简单输入错误以外的原因而未设置,请在使用它们之前进行明确检查。正如@chepner所提到的,最好自行处理异常,而不是依赖set-u。您是否有任何重要原因不只是升级到较新版本的bash?4.0.0在这一点上已经超过8年,并且有四个版本已经过时;如果不是因为macOS坚持使用3.2的特殊情况,我想任何人都会毫不犹豫地建议至少使用4.2,如果不是4.3的话。另一个解决办法是在脚本经过合理调试后关闭set-u。如果您担心变量由于简单的输入错误以外的原因而未设置,请在使用它们之前进行明确检查。