Ich versuche, ein Bash-Skript zum Testen zu schreiben, das einen Parameter verwendet und ihn über Curl an die Website sendet. Ich muss den Wert per URL codieren, um sicherzustellen, dass Sonderzeichen ordnungsgemäß verarbeitet werden. Was ist der beste Weg, dies zu tun?
Hier ist mein bisheriges Basisskript:
#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
Antworten:
Verwenden Sie
curl --data-urlencode
; vonman curl
:Anwendungsbeispiel:
Weitere Informationen finden Sie auf der Manpage .
Dies erfordert Curl 7.18.0 oder neuer (veröffentlicht im Januar 2008) . Verwenden
curl -V
Sie diese , um zu überprüfen, welche Version Sie haben.Sie können auch die Abfragezeichenfolge codieren :
quelle
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
. Irgendeine Idee warum? `"
‽Hier ist die reine BASH-Antwort.
Sie können es auf zwei Arten verwenden:
[bearbeitet]
Hier ist die passende Funktion rawurldecode (), die - bei aller Bescheidenheit - fantastisch ist.
Mit dem passenden Set können wir nun einige einfache Tests durchführen:
Und wenn Sie wirklich wirklich das Gefühl haben, dass Sie ein externes Tool benötigen (nun, es wird viel schneller gehen und möglicherweise Binärdateien und dergleichen ausführen ...), habe ich dies auf meinem OpenWRT-Router gefunden ...
Wobei url_escape.sed eine Datei war, die diese Regeln enthielt:
quelle
Jogging «à l'Hèze»
generiertJogging%20%abà%20l%27Hèze%bb
, die nicht an JS weitergeleitet werden kanndecodeURIComponent
:(\u0144
) sieht, wird es naiv% 144 ausgeben, ╡ (\u2561
) wird als% 2561 ausgegeben. Die richtigen rohurlencodierten Antworten für diese wären% C5% 84% 0A bzw.% E2% 95% A1.Verwenden Sie Perls
URI::Escape
Modul unduri_escape
Funktion in der zweiten Zeile Ihres Bash-Skripts:Bearbeiten: Behebung von Zitierproblemen, wie von Chris Johnsen in den Kommentaren vorgeschlagen. Vielen Dank!
quelle
echo
, pipe und<>
), und jetzt funktioniert es auch dann, wenn $ 2 ein Apostroph oder doppelte Anführungszeichen enthält. Vielen Dank!echo
auch:value="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$2")"
Eine andere Option ist die Verwendung
jq
(als Filter):-R
(--raw-input
) behandelt Eingabezeilen als Zeichenfolgen, anstatt sie als JSON zu analysieren, und-sR
(--slurp --raw-input
) liest die Eingabe in eine einzelne Zeichenfolge.-r
(--raw-output
) gibt den Inhalt von Zeichenfolgen anstelle von JSON-Zeichenfolgenliteralen aus.Wenn die Eingabe nicht die Ausgabe eines anderen Befehls ist, können Sie sie in a speichern
jq
Zeichenfolgenvariablen :-n
(--null-input
) liest keine Eingaben und--arg name value
speichert sievalue
Variablename
als Zeichenfolge.$name
Verweist im Filter (in einfachen Anführungszeichen, um eine Erweiterung durch die Shell zu vermeiden) auf die Variablename
.Als Bash-Funktion verpackt, wird dies:
Oder dieser Prozentsatz codiert alle Bytes:
quelle
curl
die Codierung funktioniert, und wenn bash eine integrierte Funktion hat, die akzeptabel gewesen wäre - aber esjq
scheint eine richtige Passform zu sein, mit der ich weit davon entfernt bin, das Komfortniveau zu erreichen dieses Tool)@uri
ist keine Variable, sondern ein Literal-JQ-Filter, der zum Formatieren von Strings und zum Escapezeichen verwendet wird; Siehe jq Handbuch für Details (sorry, kein direkter Link, muss@uri
auf der Seiteprintf "http://localhost:8082/" | jq -sRr '@uri'
der Vollständigkeit halber viele Lösungen mit
sed
oderawk
die einen speziellen Zeichensatz nur übersetzen, und sind daher in Bezug auf die Codegröße ziemlich groß und übersetzen auch keine anderen Sonderzeichen, die codiert werden sollten.Ein sicherer Weg zum Urlencode wäre, einfach jedes einzelne Byte zu codieren - auch die, die erlaubt gewesen wären.
xxd achtet hier darauf, dass die Eingabe als Bytes und nicht als Zeichen behandelt wird.
bearbeiten:
xxd kommt mit dem vim-common-Paket in Debian und ich war gerade auf einem System, auf dem es nicht installiert war und ich wollte es nicht installieren. Der Altornativ ist
hexdump
aus dem Paket bsdmainutils in Debian zu verwenden. Gemäß der folgenden Grafik sollten bsdmainutils und vim-common ungefähr gleich wahrscheinlich installiert werden:http://qa.debian.org/popcon-png.php?packages=vim-common%2Cbsdmainutils&show_installed=1&want_legend=1&want_ticks=1
aber trotzdem hier eine version, die
hexdump
anstelle vonxxd
und verwendet, um den aufruf zu vermeidentr
:quelle
xxd -plain
sollte NACH passierentr -d '\n'
!\n
Zeichen vonxxd -plain
in übersetzt0a
. Nehmen Sie nicht mein Wort dafür, versuchen Sie es selbst:echo -n -e '\n' | xxd -plain
Dies beweist, dass Ihrtr -d '\n'
hier nutzlos ist, da es\n
nachxxd -plain
Second keine mehr geben kann ,echo foobar
fügt\n
am Ende der Zeichenkette ein eigenes Zeichen hinzu , wird alsoxxd -plain
nichtfoobar
wie erwartet mit, sondern mit gespeistfoobar\n
. dannxxd -plain
schlägt sich in einem gewissen Zeichenkette es , dass in Enden0a
, ist es nicht geeignet für den Benutzer zu machen. Man könnte hinzufügen ,-n
umecho
es zu lösen.xxd
Anruf gehört vor dentr -d
Anruf. Es gehört dorthin, so dass jede neue Zeile in vonfoobar
übersetzt wirdxxd
. Dietr -d
nach demxxd
Aufruf ist die Zeilenumbrüche zu entfernen , dass xxd produziert. Es scheint, dass Sie nie lange genugxxd
Foobar haben, um Zeilenumbrüche zu erzeugen, aber für lange Eingaben wird dies der Fall sein. Dastr -d
ist also notwendig. Im Gegensatz zu Ihrer Annahme bestand dastr -d
NICHT darin, Zeilenumbrüche aus der Eingabe, sondern aus derxxd
Ausgabe zu entfernen . Ich möchte die Zeilenumbrüche in der Eingabe behalten. Ihr einziger gültiger Punkt ist, dass das Echo eine unnötige neue Zeile hinzufügt.echo -n
was ich tatsächlich vermisst habeEine der Varianten mag hässlich sein, aber einfach:
Hier ist zum Beispiel die Einzeiler-Version (wie von Bruno vorgeschlagen ):
quelle
date
Befehls…date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-
(Sie müssencut
die ersten 2 Zeichen deaktivieren, da die Ausgabe von curl technisch gesehen eine relative URL mit einer%0A
am Ende zu vermeiden , verwenden Sieprintf
anstelle vonecho
.Ich finde es in Python besser lesbar:
Das Triple 'stellt sicher, dass einfache Anführungszeichen nicht schaden. urllib ist in der Standardbibliothek. Es funktioniert zum Beispiel für diese verrückte (reale) URL:
quelle
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)'
hat fast keine Probleme beim Zitieren und sollte speicher- / geschwindigkeitseffizient sein (nicht überprüft, außer zum Schielen)sys.argv
als sie$value
später als Code zu analysieren. Was ist, wennvalue
enthalten''' + __import__("os").system("rm -rf ~") + '''
?python -c "import urllib;print urllib.quote(raw_input())" <<< "$data"
Ich habe das folgende Snippet nützlich gefunden, um es in eine Kette von Programmaufrufen einzufügen, in denen URI :: Escape möglicherweise nicht installiert ist:
( Quelle )
quelle
perl -pe 's/\%(\w\w)/chr hex $1/ge'
perl -pe 's/(\W)/sprintf("%%%02X", ord($1))/ge'
Buchstaben, Zahlen und Unterstriche zulassen, aber alles andere codieren.Wenn Sie
GET
request ausführen und pure curl verwenden möchten, fügen Sie einfach hinzu--get
die Lösung von @ Jacob hinzu.Hier ist ein Beispiel:
quelle
Direkter Link zur awk-Version: http://www.shelldorado.com/scripts/cmds/urlencode
Ich habe es jahrelang benutzt und es funktioniert wie ein Zauber
quelle
Dies kann der beste sein:
quelle
after=$(echo -e ...
od
Befehl ist nicht üblich.od
da es ein anderes Ausgabeformat als GNU verwendetod
. Zum Beispielprintf aa|od -An -tx1 -v|tr \ -
druckt-----------61--61--------------------------------------------------------
mit OS Xod
und-61-61
mit GNUod
. Sie könnenod -An -tx1 -v|sed 's/ */ /g;s/ *$//'|tr \ %|tr -d \\n
entweder mit OS Xod
oder GNU verwendenod
.xxd -p|sed 's/../%&/g'|tr -d \\n
macht das gleiche, obwohlxxd
es nicht in POSIX ist, sondernod
ist.Hier ist eine Bash-Lösung, die keine externen Programme aufruft:
quelle
á
Dadurch wird die Zeichenfolge in $ 1 codiert und in $ url ausgegeben. obwohl Sie es nicht in eine var setzen müssen, wenn Sie wollen. Übrigens hat das sed for tab nicht berücksichtigt, dass es in Leerzeichen umgewandelt werden würde
quelle
Verwenden von PHP aus einem Shell-Skript:
quelle
Für diejenigen unter Ihnen, die nach einer Lösung suchen, die kein Perl benötigt, ist hier eine, die nur Hexdump und Awk benötigt:
Zusammengenäht von ein paar Stellen im Internet und einigen lokalen Versuchen und Irrtümern. Es funktioniert super!
quelle
uni2ascii ist sehr praktisch:
quelle
%
-s
Sie können Javascript
encodeURIComponent
in Perl emulieren . Hier ist der Befehl:Sie können dies als Bash-Alias festlegen in
.bash_profile
:Jetzt können Sie in
encodeURIComponent
:quelle
Wenn Sie sich nicht auf Perl verlassen möchten, können Sie auch sed verwenden. Es ist ein bisschen chaotisch, da jeder Charakter einzeln entkommen muss. Erstellen Sie eine Datei mit dem folgenden Inhalt und rufen Sie sie auf
urlencode.sed
Gehen Sie wie folgt vor, um es zu verwenden.
Dadurch wird die Zeichenfolge in einen Teil aufgeteilt, der codiert werden muss, und der Teil, der in Ordnung ist, codiert den Teil, der ihn benötigt, und setzt dann wieder zusammen.
Sie können dies der Einfachheit halber in ein sh-Skript einfügen, möglicherweise einen Parameter zum Codieren verwenden, es in Ihren Pfad einfügen und dann einfach Folgendes aufrufen:
Quelle
quelle
Hier ist die Knotenversion:
quelle
node
ganz vermeiden . Ich habe eine Nur-Bash-Lösung veröffentlicht. :)node -p 'encodeURIComponent(require("fs").readFileSync(0))'
Die Frage ist, dies in Bash zu tun, und es besteht keine Notwendigkeit für Python oder Perl, da es tatsächlich einen einzigen Befehl gibt, der genau das tut, was Sie wollen - "Urlencode".
Dies ist auch viel besser, da die obige Perl-Antwort beispielsweise nicht alle Zeichen korrekt codiert. Versuchen Sie es mit dem langen Strich, den Sie von Word erhalten, und Sie erhalten die falsche Codierung.
Beachten Sie, dass "gridsite-clients" installiert sein muss, um diesen Befehl bereitzustellen.
quelle
urlencode
. Welche Version verwenden Sie?Einfache PHP-Option:
quelle
Ruby der Vollständigkeit halber
quelle
Ein weiterer PHP-Ansatz:
quelle
echo
fügt ein Zeilenumbruchzeichen (hex0xa
) hinzu. Verwenden Sie, um dies zu verhindernecho -n
.Hier ist meine Version für Busybox Ash Shell für ein eingebettetes System. Ich habe ursprünglich die Variante von Orwellophile übernommen:
quelle
Hier ist eine POSIX-Funktion, um dies zu tun:
Beispiel:
Quelle
quelle
Hier ist eine einzeilige Konvertierung mit Lua, ähnlich der Antwort von blueyed, außer dass alle nicht reservierten RFC 3986-Zeichen nicht codiert sind (wie diese Antwort ):
Außerdem müssen Sie möglicherweise sicherstellen, dass Zeilenumbrüche in Ihrer Zeichenfolge von LF in CRLF konvertiert werden. In diesem Fall können Sie eine einfügen
gsub("\r?\n", "\r\n")
vor der in die Kette .Hier ist eine Variante, die im nicht standardmäßigen Anwendungsstil / x-www-form-urlencoded diese Newline-Normalisierung durchführt und Leerzeichen als '+' anstelle von '% 20' codiert (was wahrscheinlich zum hinzugefügt werden könnte Perl-Snippet mit einer ähnlichen Technik).
quelle
Nachdem ich PHP installiert habe, benutze ich diesen Weg:
quelle
Dies ist die ksh-Version der Antwort von orwellophile, die die Funktionen rawurlencode und rawurldecode enthält (Link: Wie werden Daten für den Befehl curl codiert? ). Ich habe nicht genug Repräsentanten, um einen Kommentar zu schreiben, daher der neue Beitrag.
quelle
Was würde URLs besser analysieren als Javascript?
quelle
node -p 'encodeURIComponent(require("fs").readFileSync(0))'
echo | ...
falsch, währendecho -n | ...
der Zeilenumbruch unterdrückt wird.Das Folgende basiert auf der Antwort von Orwellophile, löst jedoch den in den Kommentaren erwähnten Multibyte-Fehler, indem LC_ALL = C gesetzt wird (ein Trick von vte.sh). Ich habe es in Form einer Funktion geschrieben, die für PROMPT_COMMAND geeignet ist, weil ich es so benutze.
quelle