J'essaie d'écrire un script bash pour les tests qui prend un paramètre et l'envoie via curl au site Web. J'ai besoin d'url encoder la valeur pour m'assurer que les caractères spéciaux sont traités correctement. Quelle est la meilleure façon de procéder?
Voici mon script de base jusqu'à présent:
#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
Réponses:
Utilisation
curl --data-urlencode
; deman curl
:Exemple d'utilisation:
Consultez la page de manuel pour plus d'informations.
Cela nécessite curl 7.18.0 ou plus récent (publié en janvier 2008) . Utilisez
curl -V
pour vérifier quelle version vous avez.Vous pouvez également encoder la chaîne de requête :
la source
curl -G --data-urlencode "blah=df ssdf sdf" --data-urlencode "blah2=dfsdf sdfsd " http://whatever.com/whatever
curl --data-urlencode "description=![image]($url)" www.example.com
. Une idée pourquoi? `"
the‽Voici la pure réponse BASH.
Vous pouvez l'utiliser de deux manières:
[édité]
Voici la fonction correspondante rawurldecode (), qui - en toute modestie - est géniale.
Avec l'ensemble correspondant, nous pouvons maintenant effectuer des tests simples:
Et si vous sentez vraiment que vous avez besoin d'un outil externe (eh bien, il ira beaucoup plus vite, et pourrait faire des fichiers binaires et autres ...) J'ai trouvé cela sur mon routeur OpenWRT ...
Où url_escape.sed était un fichier contenant ces règles:
la source
Jogging «à l'Hèze»
génèreJogging%20%abà%20l%27Hèze%bb
qui ne peut pas êtredecodeURIComponent
\u0144
), il affiche naïvement% 144, ╡ (\u2561
) est généré en tant que% 2561. Les bonnes réponses codées en brut pour celles-ci seraient respectivement% C5% 84% 0A et% E2% 95% A1.Utilisez le
URI::Escape
module et lauri_escape
fonction de Perl dans la deuxième ligne de votre script bash:Edit: Correction des problèmes de citation, comme suggéré par Chris Johnsen dans les commentaires. Merci!
la source
echo
, pipe et<>
), et maintenant cela fonctionne même lorsque $ 2 contient une apostrophe ou des guillemets doubles. Merci!echo
aussi:value="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$2")"
Une autre option consiste à utiliser
jq
(comme filtre):-R
(--raw-input
) traite les lignes d'entrée comme des chaînes au lieu de les analyser en JSON et-sR
(--slurp --raw-input
) lit l'entrée en une seule chaîne.-r
(--raw-output
) affiche le contenu des chaînes au lieu des littéraux de chaîne JSON.Si l'entrée n'est pas la sortie d'une autre commande, vous pouvez la stocker dans une
jq
variable de chaîne:-n
(--null-input
) ne lit pas l'entrée et la--arg name value
stockevalue
dans une variablename
sous forme de chaîne. Dans le filtre,$name
(entre guillemets simples, pour éviter l'expansion par le shell), référence la variablename
.Enveloppé comme une fonction Bash, cela devient:
Ou ce pourcentage encode tous les octets:
la source
curl
pour coder cela fonctionne et si bash a un intégré qui aurait été acceptable - maisjq
semble être un bon ajustement alors que je suis loin d'atteindre le niveau de confort avec cet outil)@uri
n'est pas une variable, mais un filtre jq littéral utilisé pour formater les chaînes et s'échapper; voir le manuel jq pour plus de détails (désolé, pas de lien direct, besoin de chercher@uri
sur la page ...)printf "http://localhost:8082/" | jq -sRr '@uri'
dans un souci d'exhaustivité, de nombreuses solutions utilisant
sed
ouawk
ne traduisent qu'un ensemble spécial de caractères et sont donc assez grandes par la taille du code et ne traduisent pas non plus d'autres caractères spéciaux qui devraient être encodés.un moyen sûr de coder en url serait de simplement coder chaque octet - même ceux qui auraient été autorisés.
xxd veille ici à ce que l'entrée soit traitée comme des octets et non comme des caractères.
Éditer:
xxd est livré avec le paquet vim-common dans Debian et j'étais sur un système où il n'était pas installé et je ne voulais pas l'installer. L'alternative est d'utiliser à
hexdump
partir du paquet bsdmainutils dans Debian. Selon le graphique suivant, bsdmainutils et vim-common devraient avoir une probabilité à peu près égale d'être installés:http://qa.debian.org/popcon-png.php?packages=vim-common%2Cbsdmainutils&show_installed=1&want_legend=1&want_ticks=1
mais néanmoins voici une version qui utilise à la
hexdump
place dexxd
et permet d'éviter l'tr
appel:la source
xxd -plain
devrait arriver APRÈStr -d '\n'
!\n
caractères seront traduits parxxd -plain
en0a
. Ne me croyez pas sur parole, essayez-le vous-même:echo -n -e '\n' | xxd -plain
cela prouve que votretr -d '\n'
est inutile ici car il ne peut pas y en avoir\n
aprèsxxd -plain
Second,echo foobar
ajoute son propre\n
caractère à la fin de la chaîne de caractères, doncxxd -plain
ne se nourrit pasfoobar
comme prévu mais avecfoobar\n
. puis lexxd -plain
traduit en une chaîne de caractères qui se termine par0a
, ce qui le rend inapproprié pour l'utilisateur. Vous pourriez ajouter-n
àecho
le résoudre.xxd
appel appartient en face de l'tr -d
appel. Il y appartient pour que toute nouvelle ligne enfoobar
soit traduite parxxd
. L'tr -d
après l'xxd
appel consiste à supprimer les retours à la ligne produits par xxd. Il semble que vous n'ayez jamais de foobar assez longtemps pour que celaxxd
produise des retours à la ligne, mais pour de longues entrées, cela le sera. Donc,tr -d
c'est nécessaire. Contrairement à votre hypothèse,tr -d
il ne s'agissait PAS de supprimer les retours à la ligne de l'entrée mais de laxxd
sortie. Je souhaite conserver les sauts de ligne en entrée. Votre seul point valable est que l'écho ajoute une nouvelle ligne inutile.echo -n
qui me manquait en effetL'une des variantes, peut être moche, mais simple:
Voici la version one-liner par exemple (comme suggéré par Bruno ):
la source
date
commande…date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-
(Vous devezcut
désactiver les 2 premiers caractères, car la sortie de curl est techniquement une URL relative avec une chaîne de requête.)%0A
à la fin, utilisezprintf
au lieu deecho
.Je le trouve plus lisible en python:
le triple 'garantit que les guillemets simples en valeur ne nuiront pas. urllib est dans la bibliothèque standard. Cela fonctionne pour exampple pour cette url folle (du monde réel):
la source
encoded_value=$(python3 -c "import urllib.parse; print (urllib.parse.quote('''$value'''))")
.python -c 'import urllib, sys; sys.stdout.writelines(urllib.quote_plus(l, safe="/\n") for l in sys.stdin)'
n'a presque aucun problème de citation et devrait être efficace ensys.argv
plutôt que de se substituer$value
à une chaîne plus tard analysée en tant que code. Et s'il étaitvalue
contenu''' + __import__("os").system("rm -rf ~") + '''
?python -c "import urllib;print urllib.quote(raw_input())" <<< "$data"
J'ai trouvé l'extrait de code suivant utile pour le coller dans une chaîne d'appels de programme, où URI :: Escape peut ne pas être installé:
( source )
la source
perl -pe 's/\%(\w\w)/chr hex $1/ge'
(source: unix.stackexchange.com/questions/159253/… )perl -pe 's/(\W)/sprintf("%%%02X", ord($1))/ge'
qui autorise les lettres, les chiffres et les traits de soulignement, mais encode tout le reste.Si vous souhaitez exécuter la
GET
demande et utiliser la boucle pure, ajoutez simplement--get
à la solution de @ Jacob.Voici un exemple:
la source
Lien direct vers la version awk: http://www.shelldorado.com/scripts/cmds/urlencode
Je l'ai utilisé pendant des années et cela fonctionne comme un charme
la source
Cela peut être le meilleur:
la source
after=$(echo -e ...
od
commande n'est pas courante.od
car il utilise un format de sortie différent de GNUod
. Par exemple,printf aa|od -An -tx1 -v|tr \ -
imprime-----------61--61--------------------------------------------------------
avec OS Xod
et-61-61
avec GNUod
. Vous pouvez utiliserod -An -tx1 -v|sed 's/ */ /g;s/ *$//'|tr \ %|tr -d \\n
avec OS Xod
ou GNUod
.xxd -p|sed 's/../%&/g'|tr -d \\n
fait la même chose, même s'ilxxd
n'est pas dans POSIX mais l'od
est.Voici une solution Bash qui n'invoque aucun programme externe:
la source
á
cela va encoder la chaîne à l'intérieur de $ 1 et l'afficher dans $ url. bien que vous n'ayez pas à le mettre dans un var si vous voulez. BTW n'a pas inclus le sed pour tab pensait que cela le transformerait en espaces
la source
Utiliser php à partir d'un script shell:
la source
Pour ceux d'entre vous qui recherchent une solution qui n'a pas besoin de perl, en voici une qui n'a besoin que de hexdump et awk:
Assemblé à partir de quelques endroits à travers le net et des essais et erreurs locaux. Ça marche super!
la source
uni2ascii est très pratique:
la source
%
et de l'espace (ce dernier peut être corrigé avec le-s
drapeau)Si vous ne voulez pas dépendre de Perl, vous pouvez également utiliser sed. C'est un peu compliqué, car chaque personnage doit être échappé individuellement. Créez un fichier avec le contenu suivant et appelez-le
urlencode.sed
Pour l'utiliser, procédez comme suit.
Cela divisera la chaîne en une partie qui a besoin d'encodage, et la partie qui va bien, codera la partie qui en a besoin, puis recoudra ensemble.
Vous pouvez mettre cela dans un script sh pour plus de commodité, peut-être lui faire prendre un paramètre pour encoder, le mettre sur votre chemin et ensuite vous pouvez simplement appeler:
la source
la source
Vous pouvez émuler du javascript
encodeURIComponent
en perl. Voici la commande:Vous pouvez définir ceci comme un alias bash dans
.bash_profile
:Vous pouvez maintenant accéder à
encodeURIComponent
:la source
Voici la version du nœud:
la source
node
complètement. J'ai posté une solution Bash uniquement. :)node -p 'encodeURIComponent(require("fs").readFileSync(0))'
La question est de faire cela en bash et il n'y a pas besoin de python ou de perl car il y a en fait une seule commande qui fait exactement ce que vous voulez - "urlencode".
C'est aussi beaucoup mieux, car la réponse Perl ci-dessus, par exemple, n'encode pas tous les caractères correctement. Essayez-le avec le long tiret que vous obtenez de Word et vous obtenez le mauvais encodage.
Remarque, vous devez installer "gridsite-clients" pour fournir cette commande.
la source
urlencode
. Quelle version utilisez-vous?Option PHP simple:
la source
Ruby, pour l'exhaustivité
la source
Une autre approche php:
la source
echo
ajoutera un caractère de nouvelle ligne (hex0xa
). Pour l'empêcher de faire cela, utilisezecho -n
.Voici ma version pour shell ashbox occupé pour un système embarqué, j'ai à l'origine adopté la variante d'Orwellophile:
la source
Voici une fonction POSIX pour ce faire:
Exemple:
La source
la source
Voici une conversion d'une ligne utilisant Lua, similaire à la réponse de Blueyed, sauf que tous les caractères RFC 3986 non réservés ne sont pas codés (comme cette réponse ):
En outre, vous devrez peut-être vous assurer que les sauts de ligne dans votre chaîne sont convertis de LF en CRLF, auquel cas vous pouvez insérer un
gsub("\r?\n", "\r\n")
dans la chaîne avant le pourcentage de codage.Voici une variante qui, dans le style d'application non standard / x-www-form-urlencoded , effectue cette normalisation de nouvelle ligne, ainsi que le codage des espaces en tant que '+' au lieu de '% 20' (qui pourrait probablement être ajouté à la Extrait de Perl utilisant une technique similaire).
la source
Après avoir installé php, j'utilise de cette façon:
la source
Il s'agit de la version ksh de la réponse d'orwellophile contenant les fonctions rawurlencode et rawurldecode (lien: Comment urlencoder des données pour la commande curl? ). Je n'ai pas assez de représentant pour poster un commentaire, d'où le nouveau message ..
la source
Qu'est-ce qui analyserait mieux les URL que javascript?
la source
node -p 'encodeURIComponent(require("fs").readFileSync(0))'
echo | ...
est incorrect, tout enecho -n | ...
supprimant la nouvelle ligne.Ce qui suit est basé sur la réponse d'Orwellophile, mais résout le bogue multi-octets mentionné dans les commentaires en définissant LC_ALL = C (une astuce de vte.sh). Je l'ai écrit sous forme de fonction adaptée PROMPT_COMMAND, car c'est ainsi que je l'utilise.
la source