Bash 4关联数组:错误"声明:-A:无效选项"

Joe*_*oel 52 bash associative-array

我编写了一个在bash(v 4)中使用关联数组的脚本.

它在我正在使用的本地机器上工作正常4.1.5(1)-release.

在生产计算机上,使用4.1.0(1)-release以下行声明assoc数组失败:

declare -A uniqjars
Run Code Online (Sandbox Code Playgroud)

随着消息:

/script.sh: line 11: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]
Run Code Online (Sandbox Code Playgroud)

我觉得这是一个普通的bash 4功能?

在生产机器上bash的人讨论使用,-A所以我认为它应该工作.

使用关联数组创建 .declare -A name

我可以通过打印出值来确认脚本是否正在使用正确版本的bash echo 'bash -version.

我能做错什么?

Ric*_*d H 37

确保在shell脚本(#!/bin/bash或其他)的顶部调用bash作为解释器的版本也是版本4.如果您正在执行:

bash --version
Run Code Online (Sandbox Code Playgroud)

并且它给你v4,做一个which bash检查它的位置.

  • OSX的Bash 4也可以通过[brew](http://brew.sh/)获得.但是,`/ bin/bash`需要替换为它安装的版本或符号链接. (3认同)
  • `echo "$BASH_VERSION"` 更有助于检查正在运行的实例,而不是 PATH 中第一个的版本。 (2认同)

小智 29

如果要将chars用作bash v3的数组索引,这是一个解决方法:

array=(
    'hello::world.'
    'nice::to meet you'
)

for index in "${array[@]}" ; do
    KEY="${index%%::*}"
    VALUE="${index##*::}"
    echo "$KEY - $VALUE"
done
Run Code Online (Sandbox Code Playgroud)

输出:

hello - world.
nice - to meet you
Run Code Online (Sandbox Code Playgroud)


Ben*_* W. 21

在使用Homebrew安装更新的Bash之后,以下似乎是macOS上的典型场景:

  • /bin/bash 是旧的Bash,3.2
  • /usr/local/bin/bash 是新的Bash知道关联数组(4.0或更新)
  • type bash指向/usr/local/bin/bash并且bash --version是新的(因为它解决了/usr/local/bin/bash --version)

但是,#!/bin/bash运行的shebang行的脚本./script将使用旧的Bash(问题中的场景).解决方案是:

  • 调用脚本bash script:将使用新的Bash.缺点:你总是要这样称呼它.
  • 将shebang线更改为#!/usr/local/bin/bash.缺点:在许多系统上,没有Bash /usr/local/bin,你的脚本不再可移植.
  • 将shebang线更改为#!/usr/bin/env bash.这将使用bash你的第一个PATH,它应该是新的.这很便携; 唯一的缺点是你不确切知道将执行哪个Bash.

另见这些问答:


小智 9

以下是如何bash在OS X上获取更新版本,您应该安装brew然后bash.

$ /bin/bash --version    
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin14)

$ brew install bash    
... install

$ /usr/local/bin/bash --version    
GNU bash, version 4.3.46(1)-release (x86_64-apple-darwin14.5.0)
Run Code Online (Sandbox Code Playgroud)


Tyl*_*ler 8

  1. 检查您使用此cmd的当前shell:

    echo $SHELL
    
    Run Code Online (Sandbox Code Playgroud)

    比如它可以说 /bin/bash

  2. 运行--version$SHELL:

    /bin/bash --version
    
    Run Code Online (Sandbox Code Playgroud)

    它可能输出类似的东西 GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)

    如果是在版本4之前,则必须升级.

  3. 检查您是否已经拥有版本为4的bash shell.尝试运行:

    bash --version
    
    Run Code Online (Sandbox Code Playgroud)

    如果是这样,您只需将默认shell更改为该shell.

    您可以使用这些cmds来执行此操作:

    sudo bash -c 'echo /usr/local/bin/bash >> /etc/shells'
    sudo chsh -s /usr/local/bin/bash
    
    Run Code Online (Sandbox Code Playgroud)

    第一个将shell添加到允许的shell中.第二个实际上会更改您的默认shell.


Kei*_*thJ 6

meigrafd的答案解决了我的问题,所以如果使用不正确的shebang或仍然使用bash版本3,以下允许我根据它的关联键返回一个值:

array=(
    'hello::world.'
    'nice::to meet you'
)

for index in "${array[@]}" ; do
  KEY="${index%%::*}"
  VALUE="${index##*::}"
  if [ "$KEY" == "nice" ]; then
    echo "$VALUE"
    break
  fi
done
Run Code Online (Sandbox Code Playgroud)

这将返回"与您见面"的值.