我可以在bash中将默认值分配给数组吗?

时间:2016-11-03 10:07:46

标签: bash

*我之前曾问过一个问题,但这不是正确的问题。现在我提出了正确的问题并修复了示例代码。我会提出一个答案,部分引用上一个问题的答案。 *

我想在bash中默认值为数组。请参阅以下内容,

function chmod_chown_func() {
  local file_path="$1"
  local chmod_options[2]=${2:='-R 744'}  # This line has error.
  local chown_options[2]=${3:='-R root:root'}  # This line has error.
  sudo chmod "${chmod_options[@]}" "${file_path}"
  sudo chown "${chown_options[@]}" "${file_path}"
}

chmod_chown_func "test.txt"

错误消息是

$2: cannot assign in this way

非常感谢。

3 个答案:

答案 0 :(得分:2)

以下是错误点和答案代码。

错误1: $ {variable:='some value'}的默认值不适用于位置参数。 它应该是$ {variable: - 'some value'}

错误2: 要为数组指定默认值,请声明一个数组并为其指定一个默认数组值。

示例答案代码如下

function chmod_chown_func() {
  local file_path="$1"
  local -a chmod_options=${2:-( -R 744 )}
  local -a chown_options=${3:-( -R root:root )}
  sudo chmod "${chmod_options[@]}" "${file_path}"
  sudo chown "${chown_options[@]}" "${file_path}"
}

答案 1 :(得分:1)

参数扩展

是的,展开${a:=default}会更改a的值 它在bash手册中称为"Assign Default Values"

$ unset a
$ echo "<${a}>  and  <${a:=default}>, But <${a}>"
<>  and  <default>, But <default>

但该语法无法应用于位置参数 可以(大部分)使用set更改位置参数。

$ echo "$@"
a b c
$ set -- d e f
$ echo "$@"
d e f

但您可以使用手册中调用的"Use default value"扩展名:

$ unset a
$ echo "<${a}>  and  <${a:-default}>, But <${a}>"
<>  and  <default>, But <>

将值分配给数组变量。

常见的习语是

$ array=( aaa bbb ccc )
$ echo "${array[1]}"
bbb

或者:

$ declare -a array=( aaa bbb ccc )

如果在函数内部使用,也会使函数的局部变量。

但是,它附带了通配符(*?[])将被展开的细节(除非引用或使用选项set -f)。< / p>

总体而言,最好使用read

$ IFS=' ' read -a array <<<"$a"

数组索引

您无法使用一个索引分配整个数组。这样:

chmod_options[2]=${2:-'-R 744'}

仅在索引2处创建一个数组值。更好的方法是:

chmod_options=( ${2:--R 744} )

或者,如上所述:

IFS=' ' read -a chmod_options <<<"${2:--R 744}"

答案 2 :(得分:0)

我对现有答案的运气不太好,所以不妨 KISS 并使用一点逻辑来确定数组是否为空,然后在必要时分配默认值。

local -a chmod_options="$2"
local -a chown_options="$3"
# Assign default value if chmod_options is an empty string or array
[[ -z "$chmod_options" || ${#chmod_options[@]} -eq 0 ]] && chmod_options=('-R 744')
# Assign default value if chown_options is an empty string or array
[[ -z "$chown_options" || ${#chown_options[@]} -eq 0 ]] && chown_options=('root:root')