bash关联键与变量键

  • 本文关键字:变量 bash 关联 bash
  • 更新时间 :
  • 英文 :


我尝试创建一个数组,然后使用以下命令获取键的值:

declare -A email_addresses
mail_address=(["dev"]="dev.com" ["sandbox"]="sandbox.com")
env=$(#command to get env) # result is "sandbox"
echo ${email_address[$env]}

但是它不断向我抛出此错误:-bash: "hsandbox": syntax error: operand expected (error token is ""sandbox"")

我不知道如何克服这一点。如果我这样做echo $env它会返回"sandbox"而不是""sandbox""所以我不确定似乎是什么问题。

修复"获取 env 的命令",使其输出中不发出文字引号。除非:

# strip leading and trailing quotes from env
env=${env%'"'}; env=${env#'"'}
echo "${email_address[$env]}"

Python-受众友好的解释

以一种对了解 Python 的人来说有意义的方式解释这一点(因为这是大多数 OP 代表的来源):

shell 中的echo "$foo"的行为类似于 Python 命令print str(foo),而不是 Python 命令print repr(foo)

请考虑以下 REPL 会话:

>>> mail_address = { "dev": "dev.com", "sandbox": "sandbox.com" }
>>> env = getSomething()
>>> print str(env)
"dev"
>>> print mail_address[env]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: '"dev"'
>>> print repr(env)
'"dev"'

您遇到了完全相同的问题:字典包含dev作为其文字内容,但键的文字内容"dev"


避免将来混淆:明确打印外壳变量

如果你想以一种明确的方式在shell中打印变量的内容(在Python中print repr(env)是明确的方面),echo是错误的工具。请考虑以下情况之一:

$ declare -p env           ## caveat: doesn't work for all non-printable characters
declare -- env=""dev""
$ printf 'env=%qn' "$env" ## caveat: doesn't work for non-string datatypes
env="dev"

题外话:为什么你应该总是引用参数来echo(或不使用它)

虽然它看起来无害,但代码

echo $foo

实际上有令人惊讶的复杂行为。请考虑以下事项:

foo=$'thellotworldt*n\text'

这是相当于以下 Python 的 bash:

foo='thellotworldt*n\text'

现在,让我们看看如果你实际使用echoecho $foo打印它会发生什么,如果你有一个默认值IFS并且你的 shell 是 bash:

  • 第一个选项卡完全消失
  • 其他制表符替换为空格
  • 换行符文本替换为空格
  • *将替换为当前目录中的文件列表。

也就是说,echo $foobash 中的行为相当于下面的 Python:

import itertools, glob
foo='thellotworldt*n\text'
print ' '.join(itertools.chain(*[ glob.glob(s) for s in foo.split() ]))

相比之下,请考虑:

echo "$foo"

在这种情况下,您将获得预期的行为...在巴什。

为什么是"抨击"?因为 POSIXecho标准未指定文本中包含任何反斜杠文本时的行为。 在这种情况下,echo可以做任何事情,并且仍然符合POSIX,并且BSD风格的实现的行为将与XSI风格的实现不同。

最新更新