可靠的版本无关(3.2 .. 4.4)以'-u'模式处理bash空数组的方式

时间:2016-09-25 14:09:48

标签: arrays bash

虽然Bash empty array expansion with `set -u`中建议的解决方案对我来说很有用,但最近发布的(2016/09/16)bash 4.4(例如Debian stretch中可用)中已经更改了数组处理。

$ bash --version | head -n1
bash --version | head -n1
GNU bash, version 4.4.0(1)-release (x86_64-pc-linux-gnu)

现在空数组扩展不会发出警告

$ set -u
$ arr=()
$ echo "${arr[@]}"

$ # everything is fine

相关问题中提出的解决方案因bash-4.4而失败:

$ set -u
$ arr2=()
$ arr2=( ${arr2[@] + "${arr2[@]}"} 'foo' )
bash: ${arr2[@] + "$arr2[@]"}: bad substitution

是否有人在(或多或少)版本无关的解决方案上获得建议而无需额外检查数组长度或bash版本? 我现在还在调查最新的bash更改

修改

由于我最初的问题似乎有点令人困惑,所以这里是对我试图实现的目标的澄清。 测试脚本:

#!/usr/bin/env bash
set -euo pipefail
bash --version | head -n1

arr=()

# some external environment variables are set / command line arguments passed to script
if test -n "${USE_EXTRA_ARGUMENT_1-}" ; then
  arr=( ${arr[@] + "${arr[@]}"} 'foo' )
fi

if test -n "${USE_EXTRA_ARGUMENT_2-}" ; then
  arr=( ${arr[@] + "${arr[@]}"} 'bar' )
fi

# just a dummy command
echo "${arr[@]-}"

Bash 4.3(Arch linux)运行:

$ USE_EXTRA_ARGUMENT_1=baz bash xxx.sh 
GNU bash, version 4.3.46(1)-release (x86_64-unknown-linux-gnu)
foo

Bash 4.4(Debian stretch)运行:

$ USE_EXTRA_ARGUMENT_1=baz bash xxx.sh
GNU bash, version 4.4.0(1)-release (x86_64-pc-linux-gnu)
xxx.sh: line 9: ${arr[@] + "${arr[@]}"}: bad substitution

或者我在使用bash数组时犯了严重错误?

1 个答案:

答案 0 :(得分:5)

arr2=( ${arr2[@]+"${arr2[@]}"} 'foo' ) 之前的空格是错误的;你的意思是

+=

使用arr2+=(foo) 运算符要简单得多。

let combinations (k : int) (xs : 'a list) : ('a list) seq =
    let rec loop (k : int) (xs : 'a list) : ('a list) seq = seq {
        match xs with
        | [] -> ()
        | xs when k = 1 -> for x in xs do yield [x]
        | x::xs ->
            let k' = k - 1
            for ys in loop k' xs do
                yield x :: ys
            yield! loop k xs }
    loop k xs
    |> Seq.filter (List.length >> (=)k)