Я пытаюсь написать bash-скрипт для тестирования, который принимает параметр и отправляет его через curl на веб-сайт. Мне нужно URL кодировать значение, чтобы убедиться, что специальные символы обрабатываются правильно. Каков наилучший способ сделать это?
Вот мой основной сценарий:
#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
Ответы:
Использование
curl --data-urlencode
; отman curl
:Пример использования:
Смотрите man-страницу для получения дополнительной информации.
Это требует curl 7.18.0 или новее (выпущено в январе 2008 года) . Используйте,
curl -V
чтобы проверить, какая версия у вас есть.Вы также можете закодировать строку запроса :
источник
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
. Есть идеи почему? `"
‽Вот чистый ответ BASH.
Вы можете использовать его двумя способами:
[Отредактированный]
Вот подходящая функция rawurldecode (), которая - при всей скромности - потрясающая.
Теперь с подходящим набором мы можем выполнить несколько простых тестов:
И если вы действительно чувствуете, что вам нужен внешний инструмент (ну, он будет работать намного быстрее, и может делать двоичные файлы и тому подобное ...), я нашел это на своем маршрутизаторе OpenWRT ...
Где url_escape.sed был файлом, который содержал эти правила:
источник
Jogging «à l'Hèze»
генерируетJogging%20%abà%20l%27Hèze%bb
что не может бытьdecodeURIComponent
\u0144
), он наивно выдает% 144, ╡ (\u2561
) будет выводить как% 2561. Правильные ответы с кодировкой rawurlended для них будут% C5% 84% 0A и% E2% 95% A1 соответственно.Используйте
URI::Escape
модуль иuri_escape
функцию Perl во второй строке вашего bash-скрипта:Редактировать: Исправить проблемы с цитированием, как предложено Крисом Джонсеном в комментариях. Спасибо!
источник
echo
, pipe и<>
), и теперь он работает, даже когда $ 2 содержит апостроф или двойные кавычки. Спасибо!echo
:value="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$2")"
Другим вариантом является использование
jq
(в качестве фильтра):-R
(--raw-input
) обрабатывает входные строки как строки, а не анализирует их как JSON, а-sR
(--slurp --raw-input
) считывает входные данные в одну строку.-r
(--raw-output
) выводит содержимое строк вместо строковых литералов JSON.Если ввод не является выводом другой команды, вы можете сохранить его в
jq
строковой переменной:-n
(--null-input
) не читает ввод и--arg name value
сохраняетvalue
переменнуюname
как строку. В фильтре$name
(в одинарных кавычках, чтобы избежать расширения оболочкой) ссылается на переменнуюname
.Обернутый как функция Bash, это становится:
Или этот процент кодирует все байты:
источник
curl
чтобы кодировать это работает, и если bash имеет встроенную функцию, которая была бы приемлемой - ноjq
кажется подходящей, хотя я далек от достижения уровня комфорта с этот инструмент)@uri
не какая-то переменная, а литеральный фильтр jq, используемый для форматирования строк и экранирования; подробности см. в руководстве jq (извините, прямой ссылки нет, нужно искать@uri
на странице ...)printf "http://localhost:8082/" | jq -sRr '@uri'
для полноты картины многие решения, использующие
sed
илиawk
переводят только специальный набор символов и, следовательно, имеют довольно большой размер кода, а также не переводят другие специальные символы, которые должны быть закодированы.безопасный способ urlencode - просто кодировать каждый байт - даже те, которые были бы разрешены.
Здесь xxd позаботится о том, чтобы ввод обрабатывался как байты, а не как символы.
редактировать:
xxd поставляется с пакетом vim-common в Debian, и я просто находился в системе, где он не был установлен, и я не хотел его устанавливать. Альтернативой является использование
hexdump
из пакета bsdmainutils в Debian. Согласно следующему графику, bsdmainutils и vim-common должны иметь примерно равную вероятность установки:http://qa.debian.org/popcon-png.php?packages=vim-common%2Cbsdmainutils&show_installed=1&want_legend=1&want_ticks=1
но тем не менее здесь версия, которая использует
hexdump
вместоxxd
и позволяет избежатьtr
вызова:источник
xxd -plain
должно произойти ПОСЛЕtr -d '\n'
!\n
символы будут переведеныxxd -plain
в0a
. Не верьте мне на слово, попробуйте сами:echo -n -e '\n' | xxd -plain
это доказывает, что выtr -d '\n'
здесь бесполезны, так как\n
послеxxd -plain
Second их не может быть ,echo foobar
добавляется собственный\n
символ в конец строки символов, поэтомуxxd -plain
он подается не так,foobar
как ожидалось, а сfoobar\n
. затемxxd -plain
переводит его в некоторую символьную строку, которая заканчивается0a
, что делает его непригодным для пользователя. Вы могли бы добавить-n
кecho
ее решить.xxd
вызов принадлежит передtr -d
вызовом. Он принадлежит там так, что любойfoobar
перевод строки вxxd
.tr -d
Послеxxd
вызова для удаления символов новой строки, XXD производит. Кажется, у вас никогда не было достаточно длинного foobar, чтобы онxxd
создавал переводы строк, но для длинных входов это будет. Так чтоtr -d
это необходимо. В отличие от вашего предположенияtr -d
было НЕ убирать переводы строк с ввода, а сxxd
вывода. Я хочу сохранить переводы строк во входных данных. Ваш единственный верный аргумент в том, что эхо добавляет ненужный перевод строки.echo -n
чего я действительно пропустилОдин из вариантов, может быть некрасивым, но простым:
Вот, например, однострочная версия (предложенная Бруно ):
источник
date
команды…date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-
(Вы должныcut
отключить первые 2 символа, потому что выходные данные curl - это технически относительный URL со строкой запроса.)%0A
в конце, используйтеprintf
вместоecho
.Я нахожу это более читабельным в Python:
тройка 'гарантирует, что одинарные кавычки в значении не повредят. urllib находится в стандартной библиотеке. Это работает, например, для этого сумасшедшего (реального мира) URL:
источник
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 -pe 's/\%(\w\w)/chr hex $1/ge'
(источник: unix.stackexchange.com/questions/159253/… )perl -pe 's/(\W)/sprintf("%%%02X", ord($1))/ge'
разрешить буквы, цифры и подчеркивания, но кодировать все остальное.Если вы хотите выполнить
GET
запрос и использовать чистый curl, просто добавьте--get
решение @ Jacob.Вот пример:
источник
Прямая ссылка на версию awk: http://www.shelldorado.com/scripts/cmds/urlencode
Я использовал его в течение многих лет, и он работает как шарм
источник
Это может быть лучшим:
источник
after=$(echo -e ...
od
не является общей.od
потому что он использует другой формат вывода, чем GNUod
. Например,printf aa|od -An -tx1 -v|tr \ -
печатает-----------61--61--------------------------------------------------------
с OS Xod
и-61-61
с GNUod
. Вы можете использоватьod -An -tx1 -v|sed 's/ */ /g;s/ *$//'|tr \ %|tr -d \\n
с OS Xod
или GNUod
.xxd -p|sed 's/../%&/g'|tr -d \\n
делает то же самое, хотяxxd
не в POSIX, ноod
есть.Вот решение Bash, которое не вызывает никаких внешних программ:
источник
á
это закодирует строку внутри $ 1 и выведет ее в $ url. хотя вам не нужно помещать его в переменную, если хотите. Кстати, не включает sed для табуляции, думал, что это превратит его в пробелы
источник
Использование php из сценария оболочки:
источник
Для тех из вас, кто ищет решение, не требующее Perl, вот то, которое требует только hexdump и awk:
Сшитые из нескольких мест в сети и некоторых локальных проб и ошибок. Работает отлично!
источник
uni2ascii очень удобен:
источник
%
и пробел (последнее можно исправить с помощью-s
флага)Если вы не хотите зависеть от Perl, вы также можете использовать sed. Это немного грязно, так как каждый персонаж должен избегаться индивидуально. Создайте файл со следующим содержимым и назовите его
urlencode.sed
Чтобы использовать это, сделайте следующее.
Это разделит строку на часть, которая нуждается в кодировании, и часть, которая в порядке, закодирует часть, которая нуждается в этом, затем сшит обратно.
Вы можете поместить это в сценарий sh для удобства, возможно, он будет принимать параметр для кодирования, поместить его на ваш путь, а затем вы можете просто вызвать:
источник
источник
Вы можете эмулировать JavaScript
encodeURIComponent
в Perl. Вот команда:Вы можете установить это как псевдоним bash в
.bash_profile
:Теперь вы можете перейти на
encodeURIComponent
:источник
Вот версия узла:
источник
node
вообще избежать . Я разместил решение только для Bash. :)node -p 'encodeURIComponent(require("fs").readFileSync(0))'
Вопрос в том, чтобы сделать это в bash, и нет необходимости в python или perl, так как на самом деле есть одна команда, которая делает именно то, что вы хотите - «urlencode».
Это также намного лучше, так как приведенный выше ответ на Perl, например, не правильно кодирует все символы. Попробуйте это с длинной чертой, которую вы получаете от Word, и вы получите неправильную кодировку.
Обратите внимание, что для обеспечения этой команды вам необходимо установить «gridsite-clients».
источник
urlencode
. Какую версию ты используешь?Простой вариант PHP:
источник
Рубин, для полноты
источник
Другой подход php:
источник
echo
добавит символ новой строки (hex0xa
). Чтобы остановить это, используйтеecho -n
.Вот моя версия для busybox ash shell для встроенной системы, я изначально принял вариант Orwellophile:
источник
Вот функция POSIX, чтобы сделать это:
Пример:
Источник
источник
Вот преобразование в одну строку с использованием Lua, похожее на ответ blueyed, за исключением того, что все незарезервированные символы RFC 3986 остались незакодированными (как этот ответ ):
Кроме того, вам может потребоваться убедиться, что переводы строки в вашей строке преобразуются из LF в CRLF, и в этом случае вы можете вставить
gsub("\r?\n", "\r\n")
в цепочку перед кодированием процента.Вот вариант, который в нестандартном стиле application / x-www-form-urlencoded выполняет нормализацию новой строки, а также кодирует пробелы как «+» вместо «% 20» (что, вероятно, можно добавить к Фрагмент Perl с использованием аналогичной техники).
источник
После установки php я использую этот способ:
источник
Это ksh-версия ответа orwellophile, содержащая функции rawurlencode и rawurldecode (ссылка: Как urlencode данных для команды curl? ). У меня недостаточно репутации, чтобы оставить комментарий, отсюда и новый пост ..
источник
Что будет разбирать URL лучше, чем JavaScript?
источник
node -p 'encodeURIComponent(require("fs").readFileSync(0))'
echo | ...
неправильно, хотяecho -n | ...
подавляет перевод строки.Следующее основано на ответе Орвеллофила, но решает многобайтовую ошибку, упомянутую в комментариях, путем установки LC_ALL = C (трюк из vte.sh). Я написал это в форме функции, подходящей PROMPT_COMMAND, потому что именно так я ее использую.
источник