Обрабатывает ли shell полное содержимое без экранирующего символа? - PullRequest
0 голосов
/ 18 января 2019

Мой сценарий оболочки выглядит следующим образом:

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

Мое ожидаемое значение (УВЕДОМЛЕНИЕ "):

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

НЕ

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

: И я не хочу использовать escape-символ , как? как содержимое вставить в тег XML "<![CDATA[..."..]]>"

1 Ответ

0 голосов
/ 18 января 2019

echo не ваша проблема.(Это проблема , но не ваша немедленная проблема).

Ваша проблема в том, что ваши кавычки вообще не присваиваются переменной.Кавычки: синтаксис для bash;он читает их как часть инструкций о том, как разобрать строку.Следовательно, они потребляются самим bash и не назначаются в качестве значения, если они сами не заключены в кавычки или не экранированы.


Чтобы сделать все это буквальным, вы можете поместить всю строку в одинарные кавычки:

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

... или вы можете сгенерировать его с помощью heredoc, что приведет к снижению эффективности:

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

Если вы хотите выполнить расширения, заменив account0 на имяпеременной оболочки с одноименным названием, неправильный способ сделать это - переключиться из контекста в одинарных кавычках в контекст в двойных кавычках, прежде чем на ваши переменные будут ссылаться:

# 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"

... или переключиться на heredoc без кавычек (используя <<EOF, а не <<'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"

И right способ сделать это - использовать jqсоздать безопасный экранированный JSON, содержащий ваши буквальные значения:

# 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"

И помните, где я сказал, что echo является проблемой, даже если это не ваша непосредственная проблема?См. Раздел ИСПОЛЬЗОВАНИЕ ПРИЛОЖЕНИЯ в его спецификации POSIX , чтобы понять, почему это ненадежно при обработке произвольных данных, учитывая, что bash можно настроить во время выполнения так, чтобы он вел себя в соответствии с любым из вариантов, описанных в этой спецификации.Используйте printf '%s\n' "$foo" вместо echo "$foo", чтобы получить согласованное и надежное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...