테스트를 위해 매개 변수를 사용하고 curl을 통해 웹 사이트로 보내는 bash 스크립트를 작성하려고합니다. 특수 문자가 올바르게 처리되도록 값을 URL 인코딩해야합니다. 가장 좋은 방법은 무엇입니까?
지금까지 내 기본 스크립트는 다음과 같습니다.
#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
테스트를 위해 매개 변수를 사용하고 curl을 통해 웹 사이트로 보내는 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:
이것은
--dataURL 인코딩을 수행한다는 점을 제외 하고 다른 옵션과 마찬가지로 데이터를 게시합니다 . CGI 규격을 준수하려면<data>부품 이름과 구분 기호 및 내용 사양으로 시작해야합니다.
사용법 예 :
curl \
--data-urlencode "paramName=value" \
--data-urlencode "secondParam=value" \
http://example.com
자세한 내용 은 매뉴얼 페이지 를 참조하십시오.
curl 7.18.0 이상 (2008 년 1 월 릴리스) 이 필요합니다 . 사용 curl -V중인 버전을 확인하는 데 사용하십시오 .
쿼리 문자열을 인코딩 할 수도 있습니다 .
curl -G \
--data-urlencode "p1=value 1" \
--data-urlencode "p2=value 2" \
http://example.com
# http://example.com?p1=value%201&p2=value%202
curl -G --data-urlencode "blah=df ssdf sdf" --data-urlencode "blah2=dfsdf sdfsd " http://whatever.com/whatever
curl --data-urlencode "description=" www.example.com. 왜 그런지 알아? `
"‽
다음은 순수한 BASH 답변입니다.
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}
[편집]
일치하는 rawurldecode () 함수는 다음과 같습니다.
# 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
그리고 정말로 외부 도구가 필요하다고 생각한다면 (더 빨리 가고, 바이너리 파일 등을 할 수 있습니다 ...) OpenWRT 라우터에서 이것을 찾았습니다 ...
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
Jogging «à l'Hèze»생성 Jogging%20%abà%20l%27Hèze%bb즉 JS로 공급 될 수없는 decodeURIComponent:(
\u0144) 과 같은 문자가 보이면 순전히 % 144를 출력하고 ╡ ( \u2561)는 % 2561로 출력합니다. 이에 대한 올바른 원시 코드화 된 답변은 각각 % C5 % 84 % 0A 및 % E2 % 95 % A1입니다.
bash 스크립트의 두 번째 줄에서 Perl의 URI::Escape모듈과 uri_escape기능을 사용하십시오 .
...
value="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$2")"
...
편집 : 주석에서 Chris Johnsen이 제안한대로 인용 문제를 수정 하십시오 . 감사!
echo하고 (use , pipe 및 <>) $ 2에 아포스트로피 또는 큰 따옴표가 포함되어 있어도 작동합니다. 감사!
echo:value="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$2")"
또 다른 옵션은 jq필터 로 사용 하는 것입니다.
jq -sRr @uri
-R( --raw-input)는 입력 라인을 JSON으로 구문 분석하는 대신 문자열로 취급하고 -sR( --slurp --raw-input)는 입력을 단일 문자열로 읽습니다. -r( --raw-output)는 JSON 문자열 리터럴 대신 문자열의 내용을 출력합니다.
입력이 다른 명령의 출력이 아닌 경우 jq문자열 변수 에 저장할 수 있습니다 .
jq -nr --arg v "my shell string" '$v|@uri'
-n( --null-input)는 입력을 읽지 않고 변수 에 문자열로 --arg name value저장 합니다. 쉘에서 확장을 피하기 위해 작은 따옴표로 묶인 필터 에서 변수를 참조합니다 .valuename$namename
Bash 함수로 감싸 인 다음과 같습니다.
function uriencode { jq -nr --arg v "$1" '$v|@uri'; }
또는이 백분율은 모든 바이트를 인코딩합니다.
xxd -p|tr -d \\n|sed 's/../%&/g'
curl인코딩에 그 작품과 bash는 허용했을 내장 명령이있는 경우 -하지만 jq내가 가진 안락 수준을 달성에서 멀리 해요 그래도 오른쪽에 맞는 것 같아 이 도구)
printf "http://localhost:8082/" | jq -sRr '@uri'
완벽을 기하기 위해 많은 문자를 사용 sed하거나 awk특수 문자 세트 만 변환하므로 코드 크기에 따라 크기가 크며 인코딩해야하는 다른 특수 문자도 변환하지 않습니다.
urlencode의 안전한 방법은 모든 단일 바이트를 인코딩하는 것입니다.
echo -ne 'some random\nbytes' | xxd -plain | tr -d '\n' | sed 's/\(..\)/%\1/g'
여기서 xxd는 입력이 문자가 아닌 바이트로 처리되도록주의하고 있습니다.
편집하다:
xxd는 데비안에서 vim-common 패키지와 함께 제공되며 설치되지 않은 시스템에 설치하고 싶지 않았습니다. 대안은 hexdump데비안의 bsdmainutils 패키지에서 사용 하는 것입니다. 다음 그래프에 따르면 bsdmainutils 및 vim-common은 설치 될 가능성이 거의 동일해야합니다.
그럼에도 불구하고 여기서는 hexdump대신에 사용 xxd하고 tr전화 를 피할 수 있는 버전이 있습니다 .
echo -ne 'some random\nbytes' | hexdump -v -e '/1 "%02x"' | sed 's/\(..\)/%\1/g'
xxd -plain후에 일어날 것입니다 tr -d '\n'!
\n문자로 변환됩니다 xxd -plain에 0a. 내 말을 받아들이지 말고 직접 시도해보십시오. echo -n -e '\n' | xxd -plain이것은 당신 tr -d '\n'이 여기에서 쓸모가 없다는 것을 증명합니다. 두 번째 \n이후 에는 불가능합니다. 문자열의 끝에 자체 문자를 추가 하므로 예상대로 공급되지 않지만으로 공급 됩니다 . 그런 다음 로 끝나는 문자열로 변환 하여 사용자에게 적합하지 않습니다. 당신은 그것을 해결하기 위해 추가 할 수 있습니다 . xxd -plainecho foobar\nxxd -plainfoobarfoobar\nxxd -plain0a-necho
xxd호출 은 호출 앞에 속합니다 tr -d. 개행 문자가 foobar로 번역 되도록 거기에 속합니다 xxd. 는 tr -d애프터 xxd전화 xxd가 생산하는 뉴 라인을 제거하는 것입니다. 줄 xxd바꿈 을 생성 할만 큼 foobar가 충분하지 않은 것처럼 보이지만 입력이 길면 줄어 듭니다. 그래서 tr -d필요합니다. 가정과 달리 tr -d입력에서 줄 바꿈을 제거하는 것이 아니라 xxd출력 에서 줄 바꿈을 제거 하는 것이 었습니다 . 줄 바꿈을 입력에 유지하고 싶습니다. 유일한 요점은 에코가 불필요한 줄 바꿈을 추가한다는 것입니다.
echo -n내가 실제로 놓친 것을 제외하고는 당신이 틀렸다고 생각합니다.
변형 중 하나는 추악하지만 단순 할 수 있습니다.
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
}
예를 들어 Bruno에서 제안한 것처럼 한 줄짜리 버전이 있습니다 .
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/'
date명령을 ... date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-(당신은에있는 cut컬의 출력은 쿼리 문자열과 함께 기술적으로 상대 URL이기 때문에, 오프 첫 두 문자.)
%0A마지막에 피하려면 printf대신을 사용하십시오 echo.
파이썬에서 더 읽기 쉽습니다.
encoded_value=$(python -c "import urllib; print urllib.quote('''$value''')")
트리플 '은 값의 작은 따옴표가 아프지 않도록합니다. urllib은 표준 라이브러리에 있습니다. 이 미친 (실제) URL의 예를 들어 작동합니다.
"http://www.rai.it/dl/audio/" "1264165523944Ho servito il re d'Inghilterra - Puntata 7
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)'인용 문제가 거의 없으며 메모리 / 속도 효율적 이어야 합니다 (확인하지 않았으며,
sys.argv대체 하는 것보다 참조하는 것이 훨씬 안전 $value합니다. value포함 된 경우 어떻게 ''' + __import__("os").system("rm -rf ~") + '''합니까?
python -c "import urllib;print urllib.quote(raw_input())" <<< "$data"
URI :: Escape가 설치되지 않은 일련의 프로그램 호출에 충실하는 데 유용한 다음 코드를 발견했습니다.
perl -p -e 's/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg'
( 소스 )
perl -pe 's/\%(\w\w)/chr hex $1/ge'(소스 unix.stackexchange.com/questions/159253/... )
perl -pe 's/(\W)/sprintf("%%%02X", ord($1))/ge'문자, 숫자 및 밑줄을 허용하지만 다른 모든 문자는 인코딩하도록 단순화 할 수 있습니다 .
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 ""
}
' "$@"
이것은 가장 좋은 것일 수 있습니다.
after=$(echo -e "$before" | od -An -tx1 | tr ' ' % | xargs printf "%s")
after=$(echo -e ...
od명령은 일반적이지 않습니다.
odGNU와 다른 출력 형식을 사용하기 때문에 OS X에서는 작동하지 않습니다 od. 예를 들어 OS X 및 GNU로 printf aa|od -An -tx1 -v|tr \ -인쇄합니다 . OS X 또는 GNU 와 함께 사용할 수 있습니다 . POSIX에는 없지만 동일한 작업을 수행합니다 . -----------61--61--------------------------------------------------------od-61-61odod -An -tx1 -v|sed 's/ */ /g;s/ *$//'|tr \ %|tr -d \\nododxxd -p|sed 's/../%&/g'|tr -d \\nxxdod
외부 프로그램을 호출하지 않는 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"
펄이 필요없는 솔루션을 찾는 사람들에게는 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
'`
}
그물을 가로 지르는 두 곳과 현지 시행 착오에서 함께 바느질되었습니다. 잘 작동합니다!
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
encodeURIComponent펄에서 자바 스크립트를 에뮬레이트 할 수 있습니다 . 명령은 다음과 같습니다.
perl -pe 's/([^a-zA-Z0-9_.!~*()'\''-])/sprintf("%%%02X", ord($1))/ge'
다음에서 이것을 bash 별명으로 설정할 수 있습니다 .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!
노드 버전은 다음과 같습니다.
uriencode() {
node -p "encodeURIComponent('${1//\'/\\\'}')"
}
node완전히 피할 수 있습니다. Bash 전용 솔루션을 게시했습니다. :)
node -p 'encodeURIComponent(require("fs").readFileSync(0))'
문제는 bash에서 이것을하는 것에 관한 것이며 실제로 원하는 것을 수행하는 단일 명령 인 "urlencode"가 있기 때문에 파이썬이나 perl이 필요하지 않습니다.
value=$(urlencode "${2}")
예를 들어 위의 펄 대답이 모든 문자를 올바르게 인코딩하지 않기 때문에 훨씬 좋습니다. Word에서 얻은 긴 대시로 시도하고 잘못된 인코딩을 얻습니다.
이 명령을 제공하려면 "gridsite-clients"가 설치되어 있어야합니다.
urlencode. 어떤 버전을 사용하고 있습니까?
또 다른 PHP 접근법 :
echo "encode me" | php -r "echo urlencode(file_get_contents('php://stdin'));"
echo개행 문자 (hex 0xa)를 추가합니다 . 이를 중지하려면을 사용하십시오 echo -n.
다음은 임베디드 시스템 용 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}"
}
다음과 유사한 루아 사용하여 한 줄 변환의 의 blueyed 답을 모두 제외하고는 3986 개 예약되지 않은 문자는 RFC (같은 인코딩되지 않은 왼쪽 이 답변 ) :
url=$(echo 'print((arg[1]:gsub("([^%w%-%.%_%~])",function(c)return("%%%02X"):format(c:byte())end)))' | lua - "$1")
또한 문자열의 줄 바꿈이 LF에서 CRLF로 변환되는지 확인해야 할 경우 gsub("\r?\n", "\r\n")백분율 인코딩 전에 체인에를 삽입 할 수 있습니다 .
다음은 비표준 스타일의 application / 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")
이것은 rawurlencode 및 rawurldecode 함수를 포함하는 orwellophile의 ksh 버전입니다 (링크 : curl 명령을 위해 데이터를 urlencode하는 방법? ). 의견을 게시 할 담당자가 충분하지 않으므로 새 게시물입니다.
#!/bin/ksh93
function rawurlencode
{
typeset string="${1}"
typeset strlen=${#string}
typeset encoded=""
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) o=$(printf '%%%02x' "'$c")
esac
encoded+="${o}"
done
print "${encoded}"
}
function rawurldecode
{
printf $(printf '%b' "${1//%/\\x}")
}
print $(rawurlencode "C++") # --> C%2b%2b
print $(rawurldecode "C%2b%2b") # --> C++
자바 스크립트보다 URL을 더 잘 구문 분석하는 것은 무엇입니까?
node -p "encodeURIComponent('$url')"
node -p 'encodeURIComponent(require("fs").readFileSync(0))'
echo | ...잘못된 반면 echo -n | ...개행은 표시되지 않습니다.
다음은 Orwellophile의 답변을 기반으로하지만 LC_ALL = C (vte.sh의 트릭)를 설정하여 주석에 언급 된 멀티 바이트 버그를 해결합니다. 적절한 PROMPT_COMMAND 함수 형식으로 작성했습니다.
print_path_url() {
local LC_ALL=C
local string="$PWD"
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
printf "\033]7;file://%s%s\007" "${HOSTNAME:-}" "${encoded}"
}