Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 鲁棒函数,用于设置标量/数组变量的默认值_Bash - Fatal编程技术网

Bash 鲁棒函数,用于设置标量/数组变量的默认值

Bash 鲁棒函数,用于设置标量/数组变量的默认值,bash,Bash,我在设置工作区中当前不存在的变量的值时遇到了问题。当变量的值是标量时,有一个非常好的1-liner可以做到这一点(请参阅),但不清楚它是否适用于数组变量和其他奇怪的情况(请参阅) 我希望有更多Bash专家可以帮助我创建一个setToDefault函数,该函数可以将工作空间中的任何变量设置为默认值(通常适用于标量、数组、文件路径等) 关于如何工作的测试用例如下所示: 变量_1=(1.00 2.00 3.00) #变量_2不存在,应设置为默认值 #变量_3不存在,应设置为默认值 setToDefau

我在设置工作区中当前不存在的变量的值时遇到了问题。当变量的值是标量时,有一个非常好的1-liner可以做到这一点(请参阅),但不清楚它是否适用于数组变量和其他奇怪的情况(请参阅)

我希望有更多Bash专家可以帮助我创建一个
setToDefault
函数,该函数可以将工作空间中的任何变量设置为默认值(通常适用于标量、数组、文件路径等)

关于如何工作的测试用例如下所示:

变量_1=(1.00 2.00 3.00)
#变量_2不存在,应设置为默认值
#变量_3不存在,应设置为默认值
setToDefault变量_1“a”`
setToDefault变量_2(“a”“b”“b”“c”)
setToDefault变量_3“/带有空格的文件路径/bash将出错/”
echo${variable_1[0]}
1
echo${variable_2[2]}
“b c”
echo${variable_3[0]}
“/filepath和空格/bash将搞乱/”

这里有一个纯粹的Bash可能性:

set_to_default() {
    # $1 is variable name
    # $2, ... are arguments
    # If variable pointed by $1 is set then nothing happens
    # Otherwise, variable with name $1 is set to the value determined
    # by the subsequent parameters:
    #   * if only $2 is present, variable is set to that value
    #   * if $2, $3... are present, then variable is set to an
    #      array with fields $2, $3, ...
    (($#<2)) && return 1
    local varname=$1
    declare -p "$varname" &>/dev/null && return 0
    shift
    if (( $#==1 )); then
        printf -v "$varname" '%s' "$1"
    else
        declare -ag "$varname=( \"\$@\" )"
    fi
}
也适用于嵌入的换行符和任何您可以想象的有趣角色:

$ set_to_default banana $'a newline\nhere' '*' '' ' '
$ declare -p banana
declare -a banana='([0]="a newline
here" [1]="*" [2]="" [3]=" ")'

如果要设置仅包含一个字段的数组,请首先将其声明为数组。比较:

$ unset banana
$ set_to_default banana gorilla
$ declare -p banana
declare -- banana="gorilla"
$ unset banana
$ declare -a banana
$ set_to_default banana gorilla
$ declare -p banana
declare -a banana='([0]="gorilla")'


但是,不能将数组作为参数传递给函数。所以
设置默认变量2(“a”“b”“b c”)
是没有希望的。你能再试一次吗?这看起来很有希望。不幸的是,我实际上得到了一个“mapfile:command not found”错误(运行GNU bash,版本3.2.53(1)-release(x86_64-apple-darwin14))。
$ variable_1=( 1.00 2.00 3.00 )
$ set_to_default variable_1 "a"
$ set_to_default variable_2 "a" "b" "b c"
$ set_to_default variable_3 "/filepath with spaces/bash will mess up/"
$ declare -p "${!variable_@}"
declare -a variable_1='([0]="1.00" [1]="2.00" [2]="3.00")'
declare -a variable_2='([0]="a" [1]="b" [2]="b c")'
declare -- variable_3="/filepath with spaces/bash will mess up/"
$ set_to_default banana $'a newline\nhere' '*' '' ' '
$ declare -p banana
declare -a banana='([0]="a newline
here" [1]="*" [2]="" [3]=" ")'
$ unset banana
$ set_to_default banana gorilla
$ declare -p banana
declare -- banana="gorilla"
$ unset banana
$ declare -a banana
$ set_to_default banana gorilla
$ declare -p banana
declare -a banana='([0]="gorilla")'
set_to_default() {
    # $1 is variable name
    # $2, ... are arguments
    # If variable pointed by $1 is set then nothing happens
    # Otherwise, variable with name $1 is set to the value determined
    # by the subsequent parameters:
    #   * if only $2 is present, variable is set to that value
    #   * if $2, $3... are present, then variable is set to an
    #      array with fields $2, $3, ...
    (($#<2)) && return 1
    local varname=$1 i
    declare -p "$varname" &>/dev/null && return 0
    shift
    if (( $#==1 )); then
        printf -v "$varname" '%s' "$1"
    else
        i=0
        while IFS= read -r -d '' "$varname[$i]"; do ((++i)); done < <(printf '%s\0' "$@")
    fi
}