我编写了一个在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。
我可能做错了什么?
答案 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/bash
而bash --version
是新的(因为它解析为/usr/local/bin/bash --version
)但是,使用#!/bin/bash
运行./script
shebang行的脚本将使用旧的Bash(问题中的方案)。解决方案是:
bash script
调用脚本:将使用新的Bash。 缺点:你总是要这样称呼它。#!/usr/local/bin/bash
。 缺点:在许多系统上,/usr/local/bin
中没有Bash,您的脚本不再可移植。#!/usr/bin/env bash
。这将使用bash
中的第一个PATH
,它应该是新的shortcode
。这很便携;唯一的缺点是你不确切知道将执行哪个Bash。另见Q& A:
答案 3 :(得分:8)
使用此cmd检查当前使用的shell:
echo $SHELL
E.g。它可以说/bin/bash
在--version
上运行$SHELL
:
/bin/bash --version
可能会输出类似GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
如果是在版本4之前,则必须升级。
检查您是否已经拥有版本为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]}