Сделайте строку как действительным JSON, так и оболочкой - PullRequest
0 голосов
/ 23 декабря 2018

У меня есть массив, который я хочу преобразовать в строку JSON.Один из элементов имеет обратную черту.Это может привести к ошибке при попытке запустить команду в оболочке:

data = [["305", "John Smith", "Amy Smith`", "10/11/2008", "Medical", {"page_count"=>4}]]
json_str = data.to_json.gsub('"','\"')
cmd = "node myscript.js #{json_str}"
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
  output = [stdout.read, stderr.read]
end 

Error retrieving data: sh: 1: Syntax error: EOF in backquote substitution

Очевидное решение состоит в том, чтобы избежать обратной черты:

json_str = data.to_json.gsub('"','\"').gsub('`','\\\`')

Но я хочу избежать всех специальныхсимволы оболочки, которые могут поднять isuse.Шеллескап Руби экранирует строку, чтобы ее можно было безопасно использовать в командной строке оболочки Bourne.Вот пример:

argv = "It's better to give than to receive".shellescape
argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"

Но посмотрите, что происходит, когда я применяю его к строке JSON:

data = [["305", "John Smith", "Amy Smith`", "10/11/2008", "Medical", {"page_count"=>4}]]
data = data.to_json
 => "[[\"305\",\"John Smith\",\"Amy Smith`\",\"10/11/2008\",\"Medical\",{\"page_count\":4}]]"
data = data.to_json.shellescape

=> "\\" \\\\ "\ [\ [\\\\\\\\ "305 \\\\\\\\", \\\\\\\\ "Джон \ Смит \\\\\\\\", \\\\\\\\ "Эми \ Смит \ `\\\\\\\\", \\\\\\\\ "10/11/2008 \\\\\\\\", \\\\\\\\ "Медицинский \\\\\\\\ "\ {\\\\\\\\ "PAGE_COUNT \\\\\\\\": 4 \} \] \] \\\\ "\\""

Ясно, что это вызовет ошибку вроде:

SyntaxError: Unexpected token \ in JSON at position 0

В результате шеллскейп также будет избегать пробелов, поскольку оболочка требует пробелов для выхода.Но наличие пробелов является допустимым и необходимым JSON.Итак, как я могу избежать символов оболочки, которые могут вызвать ошибку в моей команде, не нарушая JSON?

1 Ответ

0 голосов
/ 23 декабря 2018

Снаряды для людей, а не для машин.Наличие команды, производящей команды оболочки, - это запах кода, указывающий, что вы автоматизируете не на том уровне.

Пропустите оболочку и просто запустите вашу программу с необходимыми аргументами:

data = [["305", "John Smith", "Amy Smith`", "10/11/2008", "Medical", {"page_count"=>4}]]
json_str = data.to_json
Open3.popen3("node", "myscript.js", json_str) do |stdin, stdout, stderr, wait_thr|
  output = [stdout.read, stderr.read]
end 

Поскольку оболочка не задействована, нет такой глупости, как уход за больным.

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