Правильно использовать 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}