我一直无法设置工作区中当前不存在的变量值。当变量的值是标量时,有一个非常好的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/"
答案 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")'
等等,我刚刚在评论中读到你有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
}