强大的函数来设置标量/数组变量的默认值

时间:2014-12-18 20:46:15

标签: bash

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

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

这应该如何运作的测试案例如下:

variable_1=(1.00 2.00 3.00)
#variable_2 does not exist and should be set to the default value
#variable_3 does not exist and should be set to the default value

setToDefault variable_1 "a"`
setToDefault variable_2 ("a" "b" "b c")
setToDefault variable_3 "/filepath with spaces/bash will mess up/"

echo ${variable_1[0]} 
1.00

echo ${variable_2[2]} 
"b c"

echo ${variable_3[0]}
"/filepath with spaces/bash will mess up/"

2 个答案:

答案 0 :(得分:1)

function setToDefault {
  foo=$1
  if [ "${!foo}" ]
  then
    return
  fi
  bar=$(printf '%s\n' "${@:2}" | paste -sd $'\x1f')
  if [ "$3" ]
  then
    IFS=$'\x1f' read -a $foo <<< "$bar"
  else
    read $foo <<< "$bar"
  fi
}
variable_1=(1.00 2.00 3.00)
setToDefault variable_1 a
setToDefault variable_2 a b 'b c'
setToDefault variable_3 '/filepath with spaces/bash will mess up/'
echo "${variable_1[0]}"
echo "${variable_2[2]}"
echo "${variable_3[0]}"

结果

1.00
b c
/filepath with spaces/bash will mess up/

答案 1 :(得分:1)

这是一种纯粹的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
}

基本检查:

$ 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")'

击&LT; 4

等等,我刚刚在评论中读到你有Bash 3.2,所以由于-g标志declare,这不会起作用。然后你必须明确循环:

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
}