我尝试创建一个数组,然后使用以下命令获取键的值:
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""
,所以我不确定这似乎是什么问题。
答案 0 :(得分:2)
修复你的“命令以获取env”不在其输出中发出文字引号。除非:
# strip leading and trailing quotes from env
env=${env%'"'}; env=${env#'"'}
echo "${email_address[$env]}"
以对知道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中打印变量的内容(在print repr(env)
在Python中明确无误的同一方面),echo
是错误的工具。请考虑以下其中一项:
$ declare -p env ## caveat: doesn't work for all non-printable characters
declare -- env="\"dev\""
$ printf 'env=%q\n' "$env" ## caveat: doesn't work for non-string datatypes
env=\"dev\"
echo
(或不使用它)的参数虽然它看起来无害,但代码
echo $foo
实际上有令人惊讶的复杂行为。请考虑以下事项:
foo=$'\thello\tworld\t*\n\\text'
这是与以下Python等效的bash:
foo='\thello\tworld\t*\n\\text'
现在,让我们看看如果您实际使用echo
将其打印到echo $foo
会发生什么,如果您有IFS
的默认值并且您的shell是bash:
*
将替换为当前目录中的文件列表。也就是说,echo $foo
的bash中的行为等同于以下Python:
import itertools, glob
foo='\thello\tworld\t*\n\\text'
print ' '.join(itertools.chain(*[ glob.glob(s) for s in foo.split() ]))
相比之下,请考虑:
echo "$foo"
在这种情况下,你会在bash中获得预期的行为。
为什么“在bash”?因为当文本中包含任何反斜杠文字时,POSIX standard for echo
未指定行为。 echo
在这种情况下可以做任何事情,并且仍然符合POSIX标准,而BSD风格的实现将与XSI风格的实现不同。