Bash 4 关联数组:错误“声明:-A:无效选项”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6047648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash 4 associative arrays: error "declare: -A: invalid option"
提问by Joel
I've written a script that uses associative arrays in bash (v 4).
我编写了一个在 bash (v 4) 中使用关联数组的脚本。
It works fine on my local machine which is using 4.1.5(1)-release
.
它在我使用4.1.5(1)-release
.
On the production machine, using 4.1.0(1)-release
the following line, which declares the assoc array, fails:
在生产机器上,使用4.1.0(1)-release
以下声明 assoc 数组的行失败:
declare -A uniqjars
with the message:
消息:
/script.sh: line 11: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]
I was under the impression this was a general bash 4 feature?
我的印象是这是一个通用的 bash 4 功能?
In the man for bash on the production machine it discusses using -A
so I assume it shouldwork.
在生产机器上的 bash 人中,它讨论了使用,-A
所以我认为它应该可以工作。
Associative arrays are created using
declare -A name
.
关联数组是使用 .
declare -A name
I can confirm the script is using the right version of bash by printing out the value of echo 'bash -version
.
我可以通过打印 .bash 的值来确认脚本使用的是正确版本的 bash echo 'bash -version
。
What could I be doing wrong?
我可能做错了什么?
采纳答案by Richard H
Make sure the version of bash being invoked as interpreter at the top of your shell script (#!/bin/bash
or whatever) is also version 4. If you're doing:
确保在 shell 脚本(#!/bin/bash
或其他任何)顶部作为解释器调用的 bash 版本也是版本 4。如果你正在做:
bash --version
and it's giving you v4, do a which bash
to check it's location.
它给你 v4,做一个which bash
检查它的位置。
回答by meigrafd
Here is a Workaround, if you want to use chars as array index with bash v3:
这是一个解决方法,如果您想在 bash v3 中使用字符作为数组索引:
array=(
'hello::world.'
'nice::to meet you'
)
for index in "${array[@]}" ; do
KEY="${index%%::*}"
VALUE="${index##*::}"
echo "$KEY - $VALUE"
done
Output:
输出:
hello - world.
nice - to meet you
回答by Benjamin W.
The following seems to be a typical scenario on macOS after installing a newer Bash with Homebrew:
使用 Homebrew 安装较新的 Bash 后,以下似乎是 macOS 上的典型场景:
/bin/bash
is the old Bash, 3.2/usr/local/bin/bash
is the new Bash that knows about associative arrays (4.0 or newer)type bash
points to/usr/local/bin/bash
andbash --version
is the new one (because it resolves to/usr/local/bin/bash --version
)
/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
)
However, scripts with a #!/bin/bash
shebang line that are run with ./script
will use the old Bash (the scenario in the question). Solutions are:
但是,#!/bin/bash
运行带有 shebang 行的脚本./script
将使用旧的 Bash(问题中的场景)。解决办法是:
- Call the script with
bash script
: the new Bash will be used. Disadvantage:you always have to call it like that. - Change the shebang line to
#!/usr/local/bin/bash
. Disadvantage:on many systems, there is no Bash in/usr/local/bin
and your script isn't portable any longer. - Change the shebang line to
#!/usr/bin/env bash
.This will use the firstbash
in yourPATH
, which should be the new one. This is pretty portable; the only downside is that you don't know exactly which Bash will be executed.
- 使用以下命令调用脚本
bash script
:将使用新的 Bash。缺点:你总是要这样称呼它。 - 将 shebang 行更改为
#!/usr/local/bin/bash
. 缺点:在许多系统上,没有 Bash/usr/local/bin
并且您的脚本不再具有可移植性。 - 将 shebang 行更改为
#!/usr/bin/env bash
. 这将使用bash
您的 中的第一个PATH
,这应该是新的。这是非常便携的;唯一的缺点是您不确切知道将执行哪个 Bash。
See also these Q&A:
另请参阅这些问答:
回答by khancell
Here is how to get the updated bash
version on OS X, you should install brew
and then bash
.
这是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)
回答by Tyler
Check the current shell you are using with this cmd:
echo $SHELL
E.g. it could say
/bin/bash
Run
--version
on that$SHELL
:/bin/bash --version
It may output something like
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
If it is before version 4, you'll have to upgrade.
Check if you already have a bash shell with version 4. Try running:
bash --version
If so, you just need to change your default shell to that shell.
You can use these cmds to do so:
sudo bash -c 'echo /usr/local/bin/bash >> /etc/shells' sudo chsh -s /usr/local/bin/bash
The first adds the shell to the allowed shells. The second actually changes your default shell.
检查您正在使用此 cmd 的当前 shell:
echo $SHELL
例如它可以说
/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
第一个将外壳添加到允许的外壳中。第二个实际上更改了您的默认外壳。
回答by KeithJ
meigrafd's answer solved my problem, so if using an incorrect shebang or still on bash version 3 the following allowed me to return a value based on it's associated key:
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
This will return the value "to meet you".
这将返回值“遇见你”。
回答by Mihey Mik
Nothing above helped me, so I opened /etc/shells and changed the line
- /bin/bash
to /usr/local/bin/bash
, and then reloaded it with
source /etc/shells
and now I can enjoy new possibilities of v4 of bash
上面没有什么帮助了我,所以我打开/ etc / shells中,改变了线-/bin/bash
到/usr/local/bin/bash
,然后重新加载它
source /etc/shells
,现在我可以享受庆典的V4的新的可能性
回答by anubhava
Old BASH version didn't support declare -A
syntax of declaring arrays. I suggest using either of these 2 forms to declare arrays in bash to make it compatible with older bash version of your production system:
旧的 BASH 版本不支持declare -A
声明数组的语法。我建议使用这两种形式中的任何一种在 bash 中声明数组,以使其与生产系统的旧 bash 版本兼容:
arr=( '10' '20' '30' )
echo ${arr[@]}
or
或者
arr[0]=10
arr[1]=20
arr[2]=30
echo ${arr[@]}
回答by EnterUserNameHere
Per the command:
根据命令:
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)
Notice lowercase "-a" and uppercase "-A" are "(if supported)". Also if you look at the posted error message for declare usage:
注意小写的“-a”和大写的“-A”是“(如果支持)”。另外,如果您查看已发布的错误消息以了解声明用法:
/script.sh: line 11: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]
The given options are "[-afFirtx]" showing to use a lowercase "-a" but no uppercase "-A". Compare that to the usage string from the help command. It looks as if it's just not supported on the given machine.
给定的选项是“[-afFirtx]”,显示使用小写的“-a”但不使用大写的“-A”。将其与 help 命令中的用法字符串进行比较。看起来好像在给定的机器上不支持它。
回答by Khanan
Try using a different shebang. On my Mac:
尝试使用不同的shebang。在我的 Mac 上:
$ which bash
/usr/local/bin/bash
So, this script runs fine, producing "Hello World":
所以,这个脚本运行良好,产生了“Hello World”:
#!/usr/local/bin/bash
declare -A assoc
assoc[hello]="Hello World"
echo ${assoc[hello]}