Я использую git, затем отправляю сообщение о коммите и другие части в виде JSON на сервер.
В настоящее время у меня есть:
MSG=`git log -n 1 --format=oneline | grep -o ' .\+'`
который устанавливает MSG на что-то вроде:
Calendar can't go back past today
тогда
curl -i -X POST \
-H 'Accept: application/text' \
-H 'Content-type: application/json' \
-d "{'payload': {'message': '$MSG'}}" \
'https://example.com'
В моем реальном JSON есть еще пара полей.
Это работает нормально, но, конечно, когда у меня есть сообщение о фиксации, такое как выше, с апострофом в нем, JSON становится недействительным.
Как я могу избавиться от символов, требуемых в bash? Я не знаком с этим языком, поэтому не уверен, с чего начать. Замена '
на \'
сделает работу как минимум, я подозреваю.
Использование Python:
Это решение не является чисто Баш, но это'ы неинвазивный и работает с Unicode.
json_escape () {
printf '%s' "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
}
Обратите внимание, что JSON является частью стандартной библиотеки Python уже в течение длительного времени, так что это довольно минимальный питона зависимостей.
Или с помощью PHP:
json_escape () {
printf '%s' "$1" | php -r 'echo json_encode(file_get_contents("php://stdin"));'
}
Использовать вот так:
$ json_escape "ヤホー"
"\u30e4\u30db\u30fc"
Вместо того, чтобы беспокоиться о том, как правильно цитировать данные, просто сохраните его в файл и использовать @
конструкции завиток
позволяет с опцией --сведения
. Чтобы убедиться, что выход ГИТ
правильно сбежал для использования в качестве значения JSON, мы используем такой инструмент, как `jq не генерировать JSON-файл, а не создавать его вручную.
jq -n --arg msg "$(git log -n 1 --format=oneline | grep -o ' .\+')" \
'{payload: { message: $msg }}' > git-tmp.txt
curl -i -X POST \
-H 'Accept: application/text' \
-H 'Content-type: application/json' \
-d @git-tmp.txt \
'https://example.com'
Вы также можете прочитать непосредственно из стандартного ввода с помощью-д @-; я оставляю это в качестве упражнения для читателя, чтобы построить трубопровод, который читает из
мерзавеци производит необходимую полезную нагрузку сообщения для загрузки с
завиток`.
(Подсказка: это'ы jq не ... | виться ... -д@- 'https://example.com'
)
U в
может сделать это.
Легкий, бесплатный, и написанный на C, `jq не пользуется широкой поддержкой сообщества с более чем 15к звезд на GitHub. Я лично считаю, что это очень быстрое и полезным в моей повседневной работе.
jq -aRs . <<< '猫に小判'
Объяснить,
-а
означает "ASCII выход"и-Р
означает "сырья"и-S
означает, что "включить переносы строк"и.
означает "выход корня документ JSON"и<<<
передает строку в stdin (Баш только?)Исправить пример кода, данные ОП, просто труба через jq не.
MSG=`git log -n 1 --format=oneline | grep -o ' .\+' | jq -aRs .`
Я также пытался экранировать символы в Bash для передачи данных с помощью JSON, когда наткнулся на это. Я обнаружил, что на самом деле существует более широкий список символов, которые должны быть экранированы – особенно если вы пытаетесь работать с текстом в свободной форме.
Есть два совета, которые я нашел полезными:
${string//substring/replacement}
, описанный в этой теме.В результате я придумал следующие замены Bash:
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\\/\\\\} # \
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\//\\\/} # /
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\'/\\\'} # ' (not strictly needed ?)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\"/\\\"} # "
JSON_TOPIC_RAW=${JSON_TOPIC_RAW// /\\t} # \t (tab)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//
/\\\n} # \n (newline)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^M/\\\r} # \r (carriage return)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^L/\\\f} # \f (form feed)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^H/\\\b} # \b (backspace)
На данном этапе я еще не придумал, как правильно экранировать символы Unicode, что также (по-видимому) требуется. Я обновлю свой ответ, если разберусь с этим.
Хорошо, нашел, что делать. Bash поддерживает это нативно, как и ожидалось, хотя, как всегда, синтаксис не очень-то угадывается!
По сути, ${string//substring/replacement}
возвращает то, что вы изобразили, так что вы можете использовать
MSG=${MSG//\'/\\\'}
для этого. Следующая проблема заключается в том, что первый regex больше не работает, но его можно заменить на
git log -n 1 --pretty=format:'%s'
В конце концов, мне даже не понадобилось их экранировать. Вместо этого я просто заменил все ' в JSON на \". Что ж, каждый день чему-то учишься.
git log -n 1 --format=oneline | grep -o ' .\+' | jq --slurp --raw-input
Выше линия работает для меня. см
https://github.com/stedolan/jq для более U в
инструменты
Самый простой способ-использовать [jshon][1], а command строки для разбора, читать и создавать JSON.
jshon -ы 'ваши данные сюда.' 2 и GT;/dev/нуль
[1]: http://kmkeen.com/jshon/ то "Jshon и"
Я нашел что-то подобное:
MSG=`echo $MSG | sed "s/'/\\\\\'/g"`
Это экранирует раствор, используя Perl, который избегает обратной косой черты (\
), двойная кавычка ("
В) и контрольных символов U+0000
до от U+001F
:
$ echo -ne "Hello, 🌵\n\tBye" | \
perl -pe 's/(\\(\\\\)*)/$1$1/g; s/(?!\\)(["\x00-\x1f])/sprintf("\\u%04x",ord($1))/eg;'
Hello, 🌵\u000a\u0009Bye
У меня была такая же идея, чтобы отправить сообщение с коммита после фиксации. Сначала я пробовал подобное, как автор здесь. Но потом нашла лучше и проще решение.
Просто создал php файл, который посылает сообщение и вызвать его с командой wget. в hooks/пост-получите :
wget -qO - "http://localhost/git.php"
в git.php:
chdir("/opt/git/project.git");
$git_log = exec("git log -n 1 --format=oneline | grep -o ' .\+'");
А затем создать JSON и Curl для вызова в стиле РНР