J'utilise git, puis je poste le message de validation et d'autres bits sous la forme d'une charge JSON sur un serveur.
Actuellement j'ai:
MSG=`git log -n 1 --format=oneline | grep -o ' .\+'`
qui définit MSG comme suit:
Calendar can't go back past today
puis
curl -i -X POST \
-H 'Accept: application/text' \
-H 'Content-type: application/json' \
-d "{'payload': {'message': '$MSG'}}" \
'https://example.com'
Mon vrai JSON a un autre couple de champs.
Cela fonctionne bien, mais bien sûr, lorsque j'ai un message de validation tel que celui ci-dessus avec une apostrophe, le JSON est invalide.
Comment puis-je échapper aux caractères requis dans bash? Je ne connais pas bien la langue, alors je ne sais pas par où commencer. Remplacer '
par \'
ferait le travail au minimum, je suppose.
OK, a découvert quoi faire. Bash supporte cela nativement comme prévu, bien que, comme toujours, la syntaxe ne soit pas vraiment concevable!
${string//substring/replacement}
renvoie essentiellement ce que vous voulez une image, de sorte que vous pouvez utiliser
MSG=${MSG//\'/\\\'}
Pour faire ça. Le problème suivant est que la première regex ne fonctionne plus, mais cela peut être remplacé par
git log -n 1 --pretty=format:'%s'
Finalement, je n'ai même pas eu besoin de leur échapper. Au lieu de cela, j’ai simplement échangé tous les "éléments du JSON" contre "". Vous apprenez quelque chose tous les jours.
Utilisation de Python:
Cette solution n’est pas pure bash, mais elle est non invasive et gère unicode.
json_escape () {
printf '%s' "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
}
Notez que JSON fait partie des bibliothèques python standard depuis longtemps, ce qui en fait une dépendance minimale pour Python.
Ou en utilisant PHP:
json_escape () {
printf '%s' "$1" | php -r 'echo json_encode(file_get_contents("php://stdin"));'
}
Utilisez comme si:
$ json_escape "ヤホー"
"\u30e4\u30db\u30fc"
Au lieu de vous demander comment citer correctement les données, enregistrez-les dans un fichier et utilisez la construction @
que curl
autorise avec l'option --data
. Pour vous assurer que la sortie de git
est correctement échappée pour être utilisée comme valeur JSON, utilisez un outil tel que jq
pour générer le JSON au lieu de le créer manuellement.
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'
Vous pouvez également lire directement à partir de l'entrée standard en utilisant -d @-
; Je laisse cela au lecteur comme un exercice pour construire le pipeline qui lit de git
et produit le message de charge utile correct à télécharger avec curl
.
(Indice: c'est jq ... | curl ... -d@- 'https://example.com'
)
Также пытался экранировать символы в 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)
На данном тапе я не разобрался, как парильно экранировать, как правильно экранировать, как правильно Обновлю свой ответ, если я решу это.
jq
peut le faire.
Léger, gratuit et écrit en C, jq
bénéficie du soutien de nombreuses communautés avec plus de 12,5k étoiles sur GitHub . Personnellement, je le trouve très rapide et utile dans mon flux de travail quotidien.
jq -aR . <<< '猫に小判'
Expliquer,
-a
signifie "sortie ascii"-R
signifie "entrée brute".
signifie "sortie de la racine du document JSON"<<<
passe une chaîne dans stdin (bash seulement?)Pour corriger l'exemple de code donné par l'OP, lancez simplement jq.
MSG=`git log -n 1 --format=oneline | grep -o ' .\+' | jq -aR .`
J'ai trouvé quelque chose comme ça:
MSG=`echo $MSG | sed "s/'/\\\\\'/g"`
Le moyen le plus simple consiste à utiliser jshon , un outil de ligne de commande pour analyser, lire et créer du JSON.
jshon -s 'Your data goes here.' 2>/dev/null
git log -n 1 --format=oneline | grep -o ' .\+' | jq --Slurp --raw-input
La ligne ci-dessus fonctionne pour moi. reportez-vous à https://github.com/stedolan/jq pour plus d'outils jq
C'est une solution d'échappement utilisant Perl qui échappe aux barres obliques inverses (\
), aux guillemets doubles ("
) et aux caractères de contrôle 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
J'ai eu la même idée d'envoyer un message avec le message commit après commit ... J'ai d'abord essayé de la même manière que l'auteur. Mais plus tard, nous avons trouvé une solution meilleure et plus simple.
Vous venez de créer un fichier php qui envoie un message et appelez-le avec wget . Dans hooks/post-receive:
wget -qO - "http://localhost/git.php"
dans git.php:
chdir("/opt/git/project.git");
$git_log = exec("git log -n 1 --format=oneline | grep -o ' .\+'");
Et puis créez JSON et appelez CURL dans le style PHP