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

时间:2011-05-18 16:04:01

标签: bash associative-array

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

它在使用4.1.5(1)-release的本地计算机上运行正常。

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

declare -A uniqjars

带有消息:

/script.sh: line 11: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]

我认为这是一个普遍的bash 4功能?

在生产机器上使用bash的人,它使用-A进行讨论,因此我认为应该工作。

  

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

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

我可能做错了什么?

10 个答案:

答案 0 :(得分:32)

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

bash --version

它正在给你v4,做一个which bash检查它的位置。

答案 1 :(得分:26)

如果你想使用字符串作为数组索引使用bash v3:

,这是一个变通方法
array=(
    'hello::world.'
    'nice::to meet you'
)

for index in "${array[@]}" ; do
    KEY="${index%%::*}"
    VALUE="${index##*::}"
    echo "$KEY - $VALUE"
done

输出:

hello - world.
nice - to meet you

答案 2 :(得分:14)

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

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

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

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

另见Q& A:

答案 3 :(得分:8)

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

    echo $SHELL
    

    E.g。它可以说/bin/bash

  2. --version上运行$SHELL

    /bin/bash --version
    

    可能会输出类似GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)

    的内容

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

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

    bash --version
    

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

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

    sudo bash -c 'echo /usr/local/bin/bash >> /etc/shells'
    sudo chsh -s /usr/local/bin/bash
    

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

答案 4 :(得分:7)

以下是如何在OS X上获取更新的bash版本,您应该安装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)

答案 5 :(得分: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

这将返回值"以满足您"。

答案 6 :(得分:3)

上面没有任何帮助我,所以我打开/ etc / shells并更改了这一行 - /bin/bash/usr/local/bin/bash,然后重新加载 source /etc/shells现在我可以享受bash v4的新可能性

答案 7 :(得分:2)

旧BASH版本不支持声明数组的declare -A语法。我建议使用这两种形式中的任何一种在bash中声明数组,以使其与生产系统的旧bash版本兼容:

arr=( '10' '20' '30' )
echo ${arr[@]}

arr[0]=10
arr[1]=20
arr[2]=30
echo ${arr[@]}

答案 8 :(得分:1)

根据命令:

help declare
declare: declare [-aAfFgilnrtux] [-p] [name[=value] ...]
  Set variable values and attributes.

Declare variables and give them attributes.  If no NAMEs are given,
display the attributes and values of all variables.
Options which are set attributes:
  -a        to make NAMEs indexed arrays (if supported)
  -A        to make NAMEs associative arrays (if supported)

注意小写" -a"和大写" -A"是"(如果支持)"。此外,如果您查看已发布的错误消息以声明用法:

/script.sh: line 11: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]

给定的选项是" [ - afFirtx]"显示使用小写" -a"但没有大写" -A"。将其与help命令中的用法字符串进行比较。它看起来好像在给定的机器上不受支持。

答案 9 :(得分:0)

尝试使用不同的shebang。在我的Mac上:

$ which bash
/usr/local/bin/bash

所以,这个脚本运行正常,产生“Hello World”:

#!/usr/local/bin/bash
declare -A assoc
assoc[hello]="Hello World"
echo ${assoc[hello]}