我尝试创建一个数组,然后使用以下命令获取键的值:
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'
现在,让我们看看如果你实际使用echo
用echo $foo
打印它会发生什么,如果你有一个默认值IFS
并且你的 shell 是 bash:
- 第一个选项卡完全消失
- 其他制表符替换为空格
- 换行符文本替换为空格
*
将替换为当前目录中的文件列表。
也就是说,echo $foo
bash 中的行为相当于下面的 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风格的实现不同。