关联数组:错误“声明:-A:无效选项”
我编写了一个在 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 的 man 中,它讨论了使用 -A
所以我认为它应该工作。
关联数组是使用以下命令创建的
声明 -A 名称
。
我可以通过打印 echo 'bash -version
的值来确认脚本正在使用正确的 bash 版本。
我可能做错了什么?
I've written a script that uses associative arrays in bash (v 4).
It works fine on my local machine which is using 4.1.5(1)-release
.
On the production machine, using 4.1.0(1)-release
the following line, which declares the assoc array, fails:
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?
In the man for bash on the production machine it discusses using -A
so I assume it should work.
Associative arrays are created using
declare -A name
.
I can confirm the script is using the right version of bash by printing out the value of echo 'bash -version
.
What could I be doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
以下似乎是使用 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脚本
调用脚本:将使用新的Bash。 缺点:你总是必须这样称呼它。#!/usr/local/bin/bash
。 缺点:在许多系统上,/usr/local/bin
中没有 Bash,并且您的脚本不再可移植。#!/usr/bin/env bash
。这将使用PATHbash
code>,这应该是新的。这非常便携;唯一的缺点是你不知道具体会执行哪个 Bash。另请参阅这些问答:
The following seems to be a typical scenario on macOS after installing a newer Bash with Homebrew:
/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
)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:bash script
: the new Bash will be used. Disadvantage: you always have to call it like that.#!/usr/local/bin/bash
. Disadvantage: on many systems, there is no Bash in/usr/local/bin
and your script isn't portable any longer.#!/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.See also these Q&A:
确保在 shell 脚本顶部作为解释器调用的 bash 版本(
#!/bin/bash
或其他)也是版本 4。如果您正在这样做:并且它为您提供了 v4 ,执行
which bash
来检查它的位置。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:and it's giving you v4, do a
which bash
to check it's location.如果您想在 bash v3 中使用字符作为数组索引,这里有一个解决方法:
输出:
Here is a Workaround, if you want to use chars as array index with bash v3:
Output:
以下是如何在 OS X 上获取更新的
bash
版本,您应该安装brew
,然后安装bash
。2023年,路径发生了变化。目前的一项是:
Here is how to get the updated
bash
version on OS X, you should installbrew
and thenbash
.In 2023, the path has changed. The current one is:
通过此 cmd 检查您当前使用的 shell:
例如,它可能会说
/bin/bash
在
$SHELL
上运行--version
:<前><代码>/bin/bash --版本
它可能会输出类似
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
如果是版本 4 之前的版本,则必须升级。
检查您是否已有版本 4 的 bash shell。尝试运行:
<前><代码>bash --版本
如果是这样,您只需将默认 shell 更改为该 shell。
您可以使用这些命令来执行此操作:
第一个将 shell 添加到允许的 shell 中。第二个实际上更改了您的默认 shell。
Check the current shell you are using with this cmd:
E.g. it could say
/bin/bash
Run
--version
on that$SHELL
: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:
If so, you just need to change your default shell to that shell.
You can use these cmds to do so:
The first adds the shell to the allowed shells. The second actually changes your default shell.
meigrafd 的回答解决了我的问题,因此,如果使用不正确的 shebang 或仍在 bash 版本 3 上,以下内容允许我根据其关联键返回一个值:
这将返回值“to meet you” ”。
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:
This will return the value "to meet you".
旧的 BASH 版本不支持声明数组的
declare -A
语法。我建议使用这两种形式中的任何一种在 bash 中声明数组,以使其与生产系统的旧 bash 版本兼容:或
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:or
上面没有任何帮助我,所以我打开 /etc/shells 并更改了行
-
/bin/bash
到/usr/local/bin/bash
,然后重新加载source /etc/shells
现在我可以享受 bash v4 的新可能性Nothing above helped me, so I opened /etc/shells and changed the line
-
/bin/bash
to/usr/local/bin/bash
, and then reloaded it withsource /etc/shells
and now I can enjoy new possibilities of v4 of bash根据命令:
注意小写“-a”和大写“-A”是“(如果支持)”。另外,如果您查看发布的声明用法的错误消息:
给定的选项是“[-afFirtx]”,显示使用小写“-a”但没有大写“-A”。将其与帮助命令中的用法字符串进行比较。看起来好像给定的机器不支持它。
Per the command:
Notice lowercase "-a" and uppercase "-A" are "(if supported)". Also if you look at the posted error message for declare usage:
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.
尝试使用不同的 shebang。在我的 Mac 上:
所以,这个脚本运行良好,生成“Hello World”:
Try using a different shebang. On my Mac:
So, this script runs fine, producing "Hello World":