Правильно использовать curl --data-urlencode при передаче переменной
Я пытаюсь оптимизировать свой код, и один конкретный кусок кода заимствован. Я хотел бы удалить sed, поэтому я не использую никаких внешних процессов в своем основном цикле.
function sendMsg () {
value=$(echo | sed 's/ /%20/g;s/!/%21/g;s/"/%22/g;s/#/%23/g;s/&/%26/g;s/'''/%28/g;s/(/%28/g;s/)/%29/g;s/:/%3A/g;s///%2F/g');
str="http://www.xxxx.com/api.ashx?v=1&k=$Key&a=send&w=$value";
curl -s $str;
}
я отредактировал это для ясности. Значение $просто преобразуется в правильный url для вывода с помощью команды curl в конце функции.
хотя это работает просто отлично, я в основном заинтересован в том, чтобы сделать это как можно быстрее, чтобы обработать как можно без разветвления на внешние процессы, если я мочь.
Спасибо за комментарии до сих пор!
где я нахожусь до сих пор это:
function sendMsg () {
str="http://www.xxxx.com/api.ashx?v=1&k=$Key&a=send&w=";
curl -s $str --data-urlencode "";
}
Я на правильном пути, по крайней мере?
2 ответов
во-первых, ответ на ваш вопрос: если вы делаете одну подстановку или фильтрацию, используя сопоставление шаблонов быстрее:
$ foo=${bar/old/new} # Faster
$ foo=$(sed 's/old/new/' <<<$bar # Slower
первый не требует нереста под-оболочки и запуска sed
, тогда подставляя это обратно в $foo
. Однако, если вы делаете это почти дюжину раз, я считаю, используя sed
может быть быстрее:
value=$(sed -e 's/ /%20/g' \
-e 's/!/%21/g' \
-e 's/"/%22/g' \
-e 's/#/%23/g' \
-e 's/\&/%26/g' \
-e 's/'\''/%28/g' \
-e 's/(/%28/g' \
-e 's/)/%29/g' \
-e 's/:/%3A/g' \
-e 's/\//%2F/g'<<<);
обратите внимание, что этот синтаксис легче читать, так как каждая команда подстановки находится в отдельной строке. Также обратите внимание, что <<<
устраняет необходимость Эха и трубы.
это делает только один вызов sed
в то время как сопоставление с образцом должно быть сделано несколько раз.
однако вы должны использовать --data
и --data-uuencode
вместо построения строки запроса самостоятельно:
$ curl -s http://www.xxxx.com/api.ashx \
--data v=1 \
--data k=$Key \
--data a=send \
--data-urlencode w="$value";
на --data--urlencode
будет кодировать значение $value
для вас, так что вам не придется делать это. К сожалению, этот параметр существует не во всех версиях curl
. Он был добавлен в версия 7.18.0 еще в январе 2008 года. Запустить curl --version
чтобы узнать, какая у вас версия:
$ curl --version # Life is good
curl 7.30.0 (x86_64-apple-darwin13.0) libcurl/7.30.0 SecureTransport zlib/1.2.5
$ curl --version # David Sad
curl 7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
дополнительное соглашение
при попытке этого я получаю "неподдерживаемый API versionERROR", хотя мой curl -- version сообщает 7.29.0
я не могу проверить, что у вас есть, но я решил попробовать наш сервер Дженкинса, чтобы узнать, могу ли я установить описание сборки. Я убедился, что в описании есть пробелы, поэтому он требует --data-urlencoding
. Эта команда работал:
$ curl --user dweintraub:swordfish \
--data Submit=Submit \
--data-urlencode description="This is my test descripition" \
http://jenkins.corpwad.com/jenkins/job/Admin-5.1.1/138/submitDescription
это как если бы я сделал:
$ curl -user "dweintraub:swordfish http://jenkins.corpwad.com/jenkins/job/Admin-5.1.1/138/submitDescription?Submit=Submit&desciption=This%20is%20my%20test%20descripition"
отметим, что --data
добавляет знак вопроса для вас.
(нет, swordfish
не мой пароль).
это не так сложно, как вашей команды, но это может помочь указать, где у вас возникли проблемы. У вас есть имя пользователя и пароль? Если это так, вам нужно
Если вам нужно сделать это много, накладные расходы на нерест несколько sed
процессы могут сложиться. В этом случае вы можете использовать следующие строки:
value=${1// /%20/}
value=${value//!/%21}
value=${value//\"/%22}
value=${value//\#/%23}
value=${value//&/%26}
value=${value//\'/%27}
value=${value//(/%28}
value=${value//)/%29}
value=${value//:/%3A}
value=${value//\//%2F}