Reputation: 2567
Im trying to create an array and then get the value of a key using the following commands:
declare -A email_addresses
mail_address=(["dev"]="dev.com" ["sandbox"]="sandbox.com")
env=$(#command to get env) # result is "sandbox"
echo ${email_address[$env]}
However it keeps throwing this error at me : -bash: "hsandbox": syntax error: operand expected (error token is ""sandbox"")
Im not sure how to get past this. If I do echo $env
it returns "sandbox"
and not ""sandbox""
so Im not sure what seems to be the issue.
Upvotes: 0
Views: 42
Reputation: 295472
Fix your "command to get env" to not be emitting literal quotes in its output. Barring that:
# strip leading and trailing quotes from env
env=${env%'"'}; env=${env#'"'}
echo "${email_address[$env]}"
To explain this in a manner that makes sense to folks who know Python (since that's where most of the OP's rep comes from):
echo "$foo"
in shell behaves like the Python command print str(foo)
, not the Python command print repr(foo)
.
Consider the following REPL session:
>>> 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"'
You've got the exact same problem: Your dictionary contains dev
as its literal contents, but your key's literal contents are "dev"
.
If you want to print a variable's contents in shell in a way that's unambiguous (in the same respect in which print repr(env)
is unambiguous in Python), echo
is the wrong tool for the job. Consider instead one of the following:
$ 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
(Or Not Use It)While it looks innocuous, the code
echo $foo
actually has surprisingly complicated behavior. Consider the following:
foo=$'\thello\tworld\t*\n\\text'
That's the bash equivalent to the following Python:
foo='\thello\tworld\t*\n\\text'
Now, let's see what happens if you actually use echo
to print it with echo $foo
, if you have a default value for IFS
and your shell is bash:
*
is replaced by a list of files in the current directory.That is to say, the behavior in bash of echo $foo
is equivalent to the following Python:
import itertools, glob
foo='\thello\tworld\t*\n\\text'
print ' '.join(itertools.chain(*[ glob.glob(s) for s in foo.split() ]))
By contrast, consider:
echo "$foo"
In that case, you'll get the expected behavior... in bash.
Why "in bash"? Because the POSIX standard for echo
doesn't specify behavior when any backslash literal is included in the text. echo
could do literally anything in this circumstance and still be POSIX-compliant, and BSD-style implementations will behave differently than XSI-style ones do.
Upvotes: 2