curl 명령에 대한 데이터 URLencode 방법은 무엇입니까?
파라미터를 취하여 컬을 통해 웹사이트에 전송하는 테스트용 bash 스크립트를 작성하려고 합니다.특수문자가 올바르게 처리되도록 url을 인코딩해야 합니다.어떻게 하면 좋을까요?
지금까지의 기본적인 스크립트는 다음과 같습니다.
#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
curl --data-urlencode
; ; 터 ; man curl
:
게시물은 다른 합니다.
--data
URL 인코딩을 실행하는 경우를 제외하고 옵션을 지정합니다.준거하기<data>
부품은 이름 뒤에 구분 기호와 내용 사양으로 시작해야 합니다.
사용 예:
curl \
--data-urlencode "paramName=value" \
--data-urlencode "secondParam=value" \
http://example.com
이를 위해서는 컬 7.18.0 이후(2008년 1월 출시)가 필요합니다.사용하다curl -V
어떤 버전이 있는지 확인합니다.
쿼리 문자열을 부호화할 수도 있습니다.
curl --get \
--data-urlencode "p1=value 1" \
--data-urlencode "p2=value 2" \
http://example.com
# http://example.com?p1=value%201&p2=value%202
하나의 은 ' 낫다'를 하는 것입니다.jq
:
$ printf %s 'input text'|jq -sRr @uri
input%20text
$ jq -rn --arg x 'input text' '$x|@uri'
input%20text
-r
)--raw-output
대신 는 JSON 문자열 리터럴 대신 문자열의 원시 내용을 출력합니다. -n
)--null-input
STDIN 로부터의 수
-R
)--raw-input
는 입력 하지 않고 또, JSON은 JSON으로 하지 않습니다.-sR
)--slurp --raw-input
는 입력을 단일 문자열로 읽습니다.할 수 요.-sRr
-Rr
경우 를 linefeed로 %0A
:
$ printf %s\\n multiple\ lines of\ text|jq -Rr @uri
multiple%20lines
of%20text
$ printf %s\\n multiple\ lines of\ text|jq -sRr @uri
multiple%20lines%0Aof%20text%0A
또는 이 퍼센트는 모든 바이트를 인코딩합니다.
xxd -p|tr -d \\n|sed 's/../%&/g'
다음은 순수한 BASH의 답변입니다.
업데이트: 많은 변경사항이 논의되었기 때문에 https://github.com/sfinktah/bash/blob/master/rawurlencode.inc.sh에 게시하여 누구나 PR을 발행할 수 있도록 하였습니다.
주의: 이 솔루션은 Unicode 또는 Multi-Byte 문자를 인코딩하기 위한 것이 아닙니다.이것은 BASH의 미천한 네이티브 기능과는 전혀 다릅니다.POST 또는 GET 요청에서 전달되는 인수를 파괴하는 기호(예: '&', '=' 등)만 인코딩할 수 있습니다.
매우 중요한 주의: 유니코드 변환 기능은 어떠한 언어에서도 작성하지 마십시오.회답의 끝을 참조해 주세요.
rawurlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}" # You can either set a return variable (FASTER)
REPLY="${encoded}" #+or echo the result (EASIER)... or both... :p
}
다음 두 가지 방법으로 사용할 수 있습니다.
easier: echo http://url/q?=$( rawurlencode "$args" )
faster: rawurlencode "$args"; echo http://url/q?${REPLY}
[아쉬움]
여기에 일치하는 rawuldecode() 함수가 있습니다.이 함수는 매우 훌륭합니다.
# Returns a string in which the sequences with percent (%) signs followed by
# two hex digits have been replaced with literal characters.
rawurldecode() {
# This is perhaps a risky gambit, but since all escape characters must be
# encoded, we can replace %NN with \xNN and pass the lot to printf -b, which
# will decode hex for us
printf -v REPLY '%b' "${1//%/\\x}" # You can either set a return variable (FASTER)
echo "${REPLY}" #+or echo the result (EASIER)... or both... :p
}
일치하는 세트를 사용하여 다음과 같은 간단한 테스트를 수행할 수 있습니다.
$ diff rawurlencode.inc.sh \
<( rawurldecode "$( rawurlencode "$( cat rawurlencode.inc.sh )" )" ) \
&& echo Matched
Output: Matched
만약 정말로 외부 도구가 필요하다고 느낀다면(그것은 훨씬 빠르고 바이너리 파일 등을 실행할 수 있습니다) 저는 이것을 Open에서 찾았습니다.WRT 라우터...
replace_value=$(echo $replace_value | sed -f /usr/lib/ddns/url_escape.sed)
여기서 url_escape.sed는 다음 규칙을 포함하는 파일입니다.
# sed url escaping
s:%:%25:g
s: :%20:g
s:<:%3C:g
s:>:%3E:g
s:#:%23:g
s:{:%7B:g
s:}:%7D:g
s:|:%7C:g
s:\\:%5C:g
s:\^:%5E:g
s:~:%7E:g
s:\[:%5B:g
s:\]:%5D:g
s:`:%60:g
s:;:%3B:g
s:/:%2F:g
s:?:%3F:g
s^:^%3A^g
s:@:%40:g
s:=:%3D:g
s:&:%26:g
s:\$:%24:g
s:\!:%21:g
s:\*:%2A:g
BASH로 할 수 것은 ( BASH를 사용하여)xxd
또한 UTF-8 입력을 처리할 수 있는 매우 긴 규칙 집합도 있습니다. 더 빠르고 신뢰할 수 있는 방법이 있습니다.UTF-8을 UTF-32로 디코딩하는 것은 매우 간단하지만 정확성을 가지고 하는 것은 그다지 간단한 작업이 아닙니다.단, UTF-8이 동작하지 않는 날까지 동작한다고 생각될 정도로 부정확하게 동작하는 것은 매우 간단합니다.
Unicode Consortium에서도 샘플 코드가 더 이상 실제 표준과 100% 호환되지 않는다는 것을 알게 된 후 샘플 코드를 삭제했습니다.
Unicode 표준은 끊임없이 발전하고 있으며 매우 미묘한 차이를 보이고 있습니다.함께 구현할 수 있는 모든 구현은 적절하게 준수되지 않으며, 아무리 많은 노력을 기울여도 준수 상태를 유지할 수 없습니다.
Perl을 URI::Escape
및 "discommand" (모듈)uri_escape
두 합니다.
...
value="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$2")"
...
편집: Chris Johnsen이 코멘트에서 제안한 견적 문제를 수정합니다.감사합니다!
변종 중 하나는 못생겼을 수 있지만 단순합니다.
urlencode() {
local data
if [[ $# != 1 ]]; then
echo "Usage: $0 string-to-urlencode"
return 1
fi
data="$(curl -s -o /dev/null -w %{url_effective} --get --data-urlencode "$1" "")"
if [[ $? != 3 ]]; then
echo "Unexpected error" 1>&2
return 2
fi
echo "${data##/?}"
return 0
}
예를 들어, (브루노가 제안한) 원라이너 버전은 다음과 같습니다.
date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-
# If you experience the trailing %0A, use
date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | sed -E 's/..(.*).../\1/'
위해 많은 이 사용되었습니다.sed
★★★★★★★★★★★★★★★★★」awk
는 특수한 문자 세트만 변환하기 때문에 코드 사이즈별로 상당히 크며 부호화할 필요가 있는 다른 특수 문자는 변환하지 않습니다.
urlencode를 하는 안전한 방법은 모든 바이트를 인코딩하는 것입니다. 심지어 허용된 바이트도 마찬가지입니다.
echo -ne 'some random\nbytes' | xxd -plain | tr -d '\n' | sed 's/\(..\)/%\1/g'
xxd는 입력이 문자가 아닌 바이트로 처리되도록 주의하고 있습니다.
편집:
xxd는 Debian의 vim-common 패키지와 함께 제공되며, 설치되어 있지 않은 시스템에 있기 때문에 설치하고 싶지 않았습니다., 는 '고명사'를 사용해요.hexdump
debian .bsdmainutils vim-common을 사용하다
, 에서는 '이 버전'을하고 있습니다.hexdump
xxd
해서 하겠습니다.tr
삭제:
echo -ne 'some random\nbytes' | hexdump -v -e '/1 "%02x"' | sed 's/\(..\)/%\1/g'
python이 더 읽기 쉽다고 생각합니다.
encoded_value=$(python3 -c "import urllib.parse; print urllib.parse.quote('''$value''')")
triple '는 작은 따옴표가 손상되지 않도록 합니다.urlib는 표준 라이브러리에 있습니다.예를 들어 다음과 같은 crazy(실제) URL에서 작동합니다.
"http://www.rai.it/dl/audio/" "1264165523944Ho servito il re d'Inghilterra - Puntata 7
URI:Escape가 설치되지 않을 수 있는 프로그램 호출 체인에 삽입하는 데 도움이 되는 다음 스니펫을 발견했습니다.
perl -p -e 's/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg'
(소스)
GET
.--get
@Jacob jac @ @ @ @ @ @ @ @ @ @ @ @ @.
다음은 예를 제시하겠습니다.
curl -v --get --data-urlencode "access_token=$(cat .fb_access_token)" https://graph.facebook.com/me/feed
이것이 가장 좋은 방법일 수 있습니다.
after=$(echo -e "$before" | od -An -tx1 | tr ' ' % | xargs printf "%s")
awk 버전에 대한 직접 링크: http://www.shelldorado.com/scripts/cmds/urlencode
년 잘 요.
:
##########################################################################
# Title : urlencode - encode URL data
# Author : Heiner Steven (heiner.steven@odn.de)
# Date : 2000-03-15
# Requires : awk
# Categories : File Conversion, WWW, CGI
# SCCS-Id. : @(#) urlencode 1.4 06/10/29
##########################################################################
# Description
# Encode data according to
# RFC 1738: "Uniform Resource Locators (URL)" and
# RFC 1866: "Hypertext Markup Language - 2.0" (HTML)
#
# This encoding is used i.e. for the MIME type
# "application/x-www-form-urlencoded"
#
# Notes
# o The default behaviour is not to encode the line endings. This
# may not be what was intended, because the result will be
# multiple lines of output (which cannot be used in an URL or a
# HTTP "POST" request). If the desired output should be one
# line, use the "-l" option.
#
# o The "-l" option assumes, that the end-of-line is denoted by
# the character LF (ASCII 10). This is not true for Windows or
# Mac systems, where the end of a line is denoted by the two
# characters CR LF (ASCII 13 10).
# We use this for symmetry; data processed in the following way:
# cat | urlencode -l | urldecode -l
# should (and will) result in the original data
#
# o Large lines (or binary files) will break many AWK
# implementations. If you get the message
# awk: record `...' too long
# record number xxx
# consider using GNU AWK (gawk).
#
# o urlencode will always terminate it's output with an EOL
# character
#
# Thanks to Stefan Brozinski for pointing out a bug related to non-standard
# locales.
#
# See also
# urldecode
##########################################################################
PN=`basename "$0"` # Program name
VER='1.4'
: ${AWK=awk}
Usage () {
echo >&2 "$PN - encode URL data, $VER
usage: $PN [-l] [file ...]
-l: encode line endings (result will be one line of output)
The default is to encode each input line on its own."
exit 1
}
Msg () {
for MsgLine
do echo "$PN: $MsgLine" >&2
done
}
Fatal () { Msg "$@"; exit 1; }
set -- `getopt hl "$@" 2>/dev/null` || Usage
[ $# -lt 1 ] && Usage # "getopt" detected an error
EncodeEOL=no
while [ $# -gt 0 ]
do
case "$1" in
-l) EncodeEOL=yes;;
--) shift; break;;
-h) Usage;;
-*) Usage;;
*) break;; # First file name
esac
shift
done
LANG=C export LANG
$AWK '
BEGIN {
# We assume an awk implementation that is just plain dumb.
# We will convert an character to its ASCII value with the
# table ord[], and produce two-digit hexadecimal output
# without the printf("%02X") feature.
EOL = "%0A" # "end of line" string (encoded)
split ("1 2 3 4 5 6 7 8 9 A B C D E F", hextab, " ")
hextab [0] = 0
for ( i=1; i<=255; ++i ) ord [ sprintf ("%c", i) "" ] = i + 0
if ("'"$EncodeEOL"'" == "yes") EncodeEOL = 1; else EncodeEOL = 0
}
{
encoded = ""
for ( i=1; i<=length ($0); ++i ) {
c = substr ($0, i, 1)
if ( c ~ /[a-zA-Z0-9.-]/ ) {
encoded = encoded c # safe character
} else if ( c == " " ) {
encoded = encoded "+" # special handling
} else {
# unsafe character, encode it as a two-digit hex-number
lo = ord [c] % 16
hi = int (ord [c] / 16);
encoded = encoded "%" hextab [hi] hextab [lo]
}
}
if ( EncodeEOL ) {
printf ("%s", encoded EOL)
} else {
print encoded
}
}
END {
#if ( EncodeEOL ) print ""
}
' "$@"
외부 프로그램을 호출하지 않는 Bash 솔루션은 다음과 같습니다.
uriencode() {
s="${1//'%'/%25}"
s="${s//' '/%20}"
s="${s//'"'/%22}"
s="${s//'#'/%23}"
s="${s//'$'/%24}"
s="${s//'&'/%26}"
s="${s//'+'/%2B}"
s="${s//','/%2C}"
s="${s//'/'/%2F}"
s="${s//':'/%3A}"
s="${s//';'/%3B}"
s="${s//'='/%3D}"
s="${s//'?'/%3F}"
s="${s//'@'/%40}"
s="${s//'['/%5B}"
s="${s//']'/%5D}"
printf %s "$s"
}
url=$(echo "$1" | sed -e 's/%/%25/g' -e 's/ /%20/g' -e 's/!/%21/g' -e 's/"/%22/g' -e 's/#/%23/g' -e 's/\$/%24/g' -e 's/\&/%26/g' -e 's/'\''/%27/g' -e 's/(/%28/g' -e 's/)/%29/g' -e 's/\*/%2a/g' -e 's/+/%2b/g' -e 's/,/%2c/g' -e 's/-/%2d/g' -e 's/\./%2e/g' -e 's/\//%2f/g' -e 's/:/%3a/g' -e 's/;/%3b/g' -e 's//%3e/g' -e 's/?/%3f/g' -e 's/@/%40/g' -e 's/\[/%5b/g' -e 's/\\/%5c/g' -e 's/\]/%5d/g' -e 's/\^/%5e/g' -e 's/_/%5f/g' -e 's/`/%60/g' -e 's/{/%7b/g' -e 's/|/%7c/g' -e 's/}/%7d/g' -e 's/~/%7e/g')
$1 내의 문자열을 인코딩하여 $url로 출력합니다.단, 원하는 경우 var에 입력할 필요는 없습니다.BTW에는 탭용 sed가 포함되어 있지 않습니다.공간으로 바꿀 수 있다고 생각됩니다.
셸 스크립트에서 php 사용:
value="http://www.google.com"
encoded=$(php -r "echo rawurlencode('$value');")
# encoded = "http%3A%2F%2Fwww.google.com"
echo $(php -r "echo rawurldecode('$encoded');")
# returns: "http://www.google.com"
- http://www.php.net/manual/en/function.rawurlencode.php
- http://www.php.net/manual/en/function.rawurldecode.php
Perl perl 면 면 면 면 면 면 면 、 sed 。캐릭터가 개별적으로 탈출해야 하기 때문에 조금 지저분합니다.으로 파일을 만들고, 을 '아니다'라고 .urlencode.sed
s/%/%25/g
s/ /%20/g
s/ /%09/g
s/!/%21/g
s/"/%22/g
s/#/%23/g
s/\$/%24/g
s/\&/%26/g
s/'\''/%27/g
s/(/%28/g
s/)/%29/g
s/\*/%2a/g
s/+/%2b/g
s/,/%2c/g
s/-/%2d/g
s/\./%2e/g
s/\//%2f/g
s/:/%3a/g
s/;/%3b/g
s//%3e/g
s/?/%3f/g
s/@/%40/g
s/\[/%5b/g
s/\\/%5c/g
s/\]/%5d/g
s/\^/%5e/g
s/_/%5f/g
s/`/%60/g
s/{/%7b/g
s/|/%7c/g
s/}/%7d/g
s/~/%7e/g
s/ /%09/g
이것을 사용하려면 , 다음의 조작을 클릭합니다.
STR1=$(echo "https://www.example.com/change&$ ^this to?%checkthe@-functionality" | cut -d\? -f1)
STR2=$(echo "https://www.example.com/change&$ ^this to?%checkthe@-functionality" | cut -d\? -f2)
OUT2=$(echo "$STR2" | sed -f urlencode.sed)
echo "$STR1?$OUT2"
이렇게 하면 문자열이 인코딩이 필요한 부분으로 분할되고 정상인 부분은 인코딩된 후 다시 연결됩니다.
편의상 이것을 sh 스크립트에 넣을 수 있습니다.인코딩하기 위한 파라미터를 지정하여 패스 상에 배치하면 다음과 같이 호출할 수 있습니다.
urlencode https://www.exxample.com?isThisFun=HellNo
javascript를 perl로 에뮬레이트할 수 있습니다.명령어는 다음과 같습니다.
perl -pe 's/([^a-zA-Z0-9_.!~*()'\''-])/sprintf("%%%02X", ord($1))/ge'
에일리어스는 할 수 있습니다..bash_profile
:
alias encodeURIComponent='perl -pe '\''s/([^a-zA-Z0-9_.!~*()'\''\'\'''\''-])/sprintf("%%%02X",ord($1))/ge'\'
, 이제 파이프로 .encodeURIComponent
:
$ echo -n 'hèllo wôrld!' | encodeURIComponent
h%C3%A8llo%20w%C3%B4rld!
Python 3는 2010년 @sandro의 좋은 답변을 기반으로 합니다.
echo "Test & /me" | python -c "import urllib.parse;print (urllib.parse.quote(input()))"
테스트 %20%26%20/me
이 노드 기반 응답은 인코딩을 사용합니다.stdin 위의 URIC 구성 요소:
uriencode_stdin() {
node -p 'encodeURIComponent(require("fs").readFileSync(0))'
}
echo -n $'hello\nwörld' | uriencode_stdin
hello%0Aw%C3%B6rld
perl이 필요 없는 솔루션을 찾고 계신 분들을 위해 hexdump와 awk만 필요한 솔루션을 다음에 제시하겠습니다.
url_encode() {
[ $# -lt 1 ] && { return; }
encodedurl="$1";
# make sure hexdump exists, if not, just give back the url
[ ! -x "/usr/bin/hexdump" ] && { return; }
encodedurl=`
echo $encodedurl | hexdump -v -e '1/1 "%02x\t"' -e '1/1 "%_c\n"' |
LANG=C awk '
$1 == "20" { printf("%s", "+"); next } # space becomes plus
$1 ~ /0[adAD]/ { next } # strip newlines
$2 ~ /^[a-zA-Z0-9.*()\/-]$/ { printf("%s", $2); next } # pass through what we can
{ printf("%%%s", $1) } # take hex value of everything else
'`
}
인터넷 건너편에서 몇군데서 꿰매고 지역 시행착오를 겪었어요잘 작동한다!
uni2ascii는 매우 편리합니다.
$ echo -ne '你好世界' | uni2ascii -aJ
%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C
단순 PHP 옵션:
echo 'part-that-needs-encoding' | php -R 'echo urlencode($argn);'
문제는 이것을 bash로 실행하는 것입니다.또한 실제로 원하는 것을 실행하는 명령어(urlencode)가1개 있기 때문에 python이나 perl은 필요 없습니다.
value=$(urlencode "${2}")
예를 들어 위의 perl 답변이 모든 문자를 올바르게 인코딩하지 않기 때문에 이 방법도 훨씬 좋습니다.Word에서 얻은 긴 대시로 시도하면 잘못된 인코딩이 나옵니다.
다음 명령을 사용하려면 "gridsite-clients"가 설치되어 있어야 합니다.
sudo apt install gridsite-clients
javascript보다 URL을 해석하는 것이 더 좋은 것은 무엇일까요?
node -p "encodeURIComponent('$url')"
이를 위한 POSIX 함수는 다음과 같습니다.
url_encode() {
awk 'BEGIN {
for (n = 0; n < 125; n++) {
m[sprintf("%c", n)] = n
}
n = 1
while (1) {
s = substr(ARGV[1], n, 1)
if (s == "") {
break
}
t = s ~ /[[:alnum:]_.!~*\47()-]/ ? t s : t sprintf("%%%02X", m[s])
n++
}
print t
}' "$1"
}
예:
value=$(url_encode "$2")
노드 버전은 다음과 같습니다.
uriencode() {
node -p "encodeURIComponent('${1//\'/\\\'}')"
}
또 다른 php 접근법:
echo "encode me" | php -r "echo urlencode(file_get_contents('php://stdin'));"
임베디드 시스템용 busybox ash shell 버전은 다음과 같습니다.원래 Orwellophile의 변종을 채택했습니다.
urlencode()
{
local S="${1}"
local encoded=""
local ch
local o
for i in $(seq 0 $((${#S} - 1)) )
do
ch=${S:$i:1}
case "${ch}" in
[-_.~a-zA-Z0-9])
o="${ch}"
;;
*)
o=$(printf '%%%02x' "'$ch")
;;
esac
encoded="${encoded}${o}"
done
echo ${encoded}
}
urldecode()
{
# urldecode <string>
local url_encoded="${1//+/ }"
printf '%b' "${url_encoded//%/\\x}"
}
루비, 완전성 확보
value="$(ruby -r cgi -e 'puts CGI.escape(ARGV[0])' "$2")"
다음은 Lua를 사용한 한 줄 변환입니다.모든 RFC 3986 Unreserved Characters가 부호화되지 않은 상태로 남아 있는 것을 제외하고 bluyed의 답변과 유사합니다(다음 답변과 같습니다).
url=$(echo 'print((arg[1]:gsub("([^%w%-%.%_%~])",function(c)return("%%%02X"):format(c:byte())end)))' | lua - "$1")
CRLF로 해야 할 이 경우 CRLF를 할 수 .★★★★★★★★★★★★★★★★★★·gsub("\r?\n", "\r\n")
쇠사슬을 매고 있는 것입니다.
다음은 비표준 스타일의 애플리케이션/x-www-form-urlencoded에서 줄바꿈 정규화를 수행하고 공간을 '%20'이 아닌 '+'로 인코딩하는 변형입니다(이것은 유사한 기술을 사용하여 Perl 스니펫에 추가될 수 있습니다).
url=$(echo 'print((arg[1]:gsub("\r?\n", "\r\n"):gsub("([^%w%-%.%_%~ ]))",function(c)return("%%%02X"):format(c:byte())end):gsub(" ","+"))' | lua - "$1")
이 경우는, 호스트명을 URL로 인코딩 할 필요가 있었습니다.이유는 묻지 마세요.미니멀리스트이자 Perl의 팬인 제가 생각해낸 것은 다음과 같습니다.
url_encode()
{
echo -n "$1" | perl -pe 's/[^a-zA-Z0-9\/_.~-]/sprintf "%%%02x", ord($&)/ge'
}
나한테는 딱 맞아.
언급URL : https://stackoverflow.com/questions/296536/how-to-urlencode-data-for-curl-command
'programing' 카테고리의 다른 글
VBA를 사용하여 Excel 시트에서 공백이 아닌 열 수 찾기 (0) | 2023.04.11 |
---|---|
PowerShell에서 출력을 $null로 리디렉션하지만 변수가 설정된 상태로 유지되도록 합니다. (0) | 2023.04.11 |
셸 스크립트의 kill -0 $pid는 무엇을 합니까? (0) | 2023.04.11 |
Windows에서 . (도트) 접두사를 가진 파일을 수동으로 작성하려면 어떻게 해야 합니까?예를 들어 .htaccess 입니다. (0) | 2023.04.11 |
Bash 스크립트 – "/bin/bash^M: 잘못된 인터프리터:해당 파일 또는 디렉터리 없음" (0) | 2023.04.11 |