Does shell echo complete content without escape ch

2019-03-06 16:27发布

My shell script is following:

#!/bin/bash
account0=0xf2de2e86b9b634f655e441a4e8353c9bf59352d7
passwd=123456
data={"jsonrpc":"2.0","method":"personal_unlockAccount","id":1,"params":[$account0,$passwd]}
echo $data

My expected is (NOTICE "):

{"jsonrpc":"2.0","method":"personal_unlockAccount","id":1,"params":[0xf2de2e86b9b634f655e441a4e8353c9bf59352d7,123456]}

NOT

{jsonrpc:2.0,method:personal_unlockAccount,id:1,params:[0xf2de2e86b9b634f655e441a4e8353c9bf59352d7,123456]}

: And I do not want to use escape character, how ? like content insert into xml tag "<![CDATA[..."..]]>"

标签: linux bash shell
1条回答
我想做一个坏孩纸
2楼-- · 2019-03-06 17:08

The echo isn't your problem. (It's a problem, but not your immediate problem).

Your problem is that your quotes aren't being assigned to the variable at all. Quotes are syntax to bash; it reads them as part of the instructions on how to parse a string. Consequently, they're consumed by bash itself, and not assigned as a value unless they are themselves quoted or escaped.


To make the whole thing literal, you can put the entire line in single quotes:

data='{"jsonrpc":"2.0","method":"personal_unlockAccount","id":1,"params":[$account0,$passwd]}'
echo "$data"

...or you can generate it with a heredoc, at some cost to efficiency:

{ IFS= read -r -d '' data || [[ $data ]]; } <<'EOF'
{"jsonrpc":"2.0","method":"personal_unlockAccount","id":1,"params":[$account0,$passwd]}
EOF
echo "$data"

Assuming you want to perform expansions, replacing account0 with the name of the like-named shell variable, the wrong way to do it is to switch from a single-quoted context to a double-quoted context before your variables are referenced:

# BAD: Does not guarantee result is valid JSON
account0=exampleName; passwd=examplePassword
data='{"jsonrpc":"2.0","method":"personal_unlockAccount","id":1,"params":["'"$account0"'","'"$passwd"'"]}'
echo "$data"

...or to switch to an unquoted heredoc (using <<EOF, not <<'EOF'):

# BAD: Does not guarantee result is valid JSON
account0=exampleName; passwd=examplePassword
{ IFS= read -r -d '' data || [[ $data ]]; } <<EOF
{"jsonrpc":"2.0","method":"personal_unlockAccount","id":1,"params":["$account0","$passwd"]}
EOF
echo "$data"

And the right way to do it is to use jq to generate safely-escaped JSON containing your literal values:

# GOOD: Result will always be syntactically valid JSON.
account0=exampleName; passwd=examplePassword
data=$(jq -cn --arg account0 "$account0" --arg passwd "$passwd" '
  {"jsonrpc":"2.0","method":"personal_unlockAccount","id":1,"params":[$account0,$passwd]}
')
echo "$data"

And remember where I said echo is a problem, even if it's not your immediate problem? See the APPLICATION USAGE section of its POSIX specification to understand why it's innately unreliable when handling arbitrary data, keeping in mind that bash can be configured at runtime to behave according to any of the variants described in that spec. Use printf '%s\n' "$foo" instead of echo "$foo" to get consistent and reliable behavior.

查看更多
登录 后发表回答