[TL, DR: используйте urlencode_grouped_case
версия в последнем блоке кода.]
Awk может сделать большую часть задания, за исключением того, что он раздражающе испытывает недостаток в способе преобразовать от символа до его числа. Если od
присутствует на Вашем устройстве, можно использовать его для преобразования всех символов (более точно, байты) в соответствующее число (записанный в десятичном числе, так, чтобы awk мог считать его), затем используйте awk для преобразования допустимых символов назад в литералы и заключенные в кавычки символы в надлежащую форму.
urlencode_od_awk () {
echo "$1" | od -t d1 | awk '{
for (i = 2; i <= NF; i++) {
printf(($i>=48 && $i<=57) || ($i>=65 &&$i<=90) || ($i>=97 && $i<=122) ||
$i==45 || $i==46 || $i==95 || $i==126 ?
"%c" : "%%%02x", $i)
}
}'
}
Если Ваше устройство не имеет od
, можно сделать все в оболочке; это значительно поможет производительности (меньше вызовов к внешней программе — ни один, если printf
встроенное) и быть легче записать правильно. Я полагаю, что все оболочки Busybox поддерживают ${VAR#PREFIX}
создайте для обрезки префикса от строки; используйте его для лишения первого символа строки неоднократно.
urlencode_many_printf () {
string=$1
while [ -n "$string" ]; do
tail=${string#?}
head=${string%$tail}
case $head in
[-._~0-9A-Za-z]) printf %c "$head";;
*) printf %%%02x "'$head"
esac
string=$tail
done
echo
}
Если printf
не встроенное, а внешняя утилита, Вы снова получите производительность путем вызова ее только однажды для целой функции вместо однажды на символ. Создайте формат и параметры, затем выполните единственный вызов к printf
.
urlencode_single_printf () {
string=$1; format=; set --
while [ -n "$string" ]; do
tail=${string#?}
head=${string%$tail}
case $head in
[-._~0-9A-Za-z]) format=$format%c; set -- "$@" "$head";;
*) format=$format%%%02x; set -- "$@" "'$head";;
esac
string=$tail
done
printf "$format\\n" "$@"
}
Это оптимально с точки зрения внешних вызовов (существует единственный, и Вы не можете сделать этого с чистыми конструкциями оболочки, если Вы не готовы перечислить все символы, которых нужно оставить). Если большинство символов в аргументе должно быть передано неизменное, можно обработать их в пакете.
urlencode_grouped_literals () {
string=$1; format=; set --
while
literal=${string%%[!-._~0-9A-Za-z]*}
if [ -n "$literal" ]; then
format=$format%s
set -- "$@" "$literal"
string=${string#$literal}
fi
[ -n "$string" ]
do
tail=${string#?}
head=${string%$tail}
format=$format%%%02x
set -- "$@" "'$head"
string=$tail
done
printf "$format\\n" "$@"
}
В зависимости от параметров компиляции, [
(иначе. test
) может быть внешняя утилита. Мы только используем его для сопоставления строк, которое может также быть сделано в оболочке с case
создать. Вот последние два подхода, переписанные для предотвращения test
встроенный, первый идущий символ символом:
urlencode_single_fork () {
string=$1; format=; set --
while case "$string" in "") false;; esac do
tail=${string#?}
head=${string%$tail}
case $head in
[-._~0-9A-Za-z]) format=$format%c; set -- "$@" "$head";;
*) format=$format%%%02x; set -- "$@" "'$head";;
esac
string=$tail
done
printf "$format\\n" "$@"
}
и копируя каждый литеральный сегмент в пакете:
urlencode_grouped_case () {
string=$1; format=; set --
while
literal=${string%%[!-._~0-9A-Za-z]*}
case "$literal" in
?*)
format=$format%s
set -- "$@" "$literal"
string=${string#$literal};;
esac
case "$string" in
"") false;;
esac
do
tail=${string#?}
head=${string%$tail}
format=$format%%%02x
set -- "$@" "'$head"
string=$tail
done
printf "$format\\n" "$@"
}
Я протестировал на своем маршрутизаторе (процессор MIPS, DD-WRT-based распределение, BusyBox с пеплом, внешним printf
и [
). Каждая версия является значимым улучшением скорости на предыдущем. Перемещение в единственное ветвление является старшим значащим улучшением; это - то, которое заставляет функцию ответить почти немедленно (в человеческих терминах) в противоположность после нескольких секунд для реалистического длинного параметра URL.
psql клиент находится в отдельном пакете с psql сервера. Это обычно звонило postgresql-клиенту.
Вероятно, что у Вас есть больше чем одна версия PostgreSQL, и неверная версия psql используется. Попробовать
sudo find / -name psql
Затем проверьте версию файлов и используйте правильный установкой PATH.
/usr/pgsql-9.3/bin/psql -V
psql (PostgreSQL) 9.3.2
Можно также попробовать
yum list installed | grep postgres
видеть, какие версии PostgreSQL находятся там в Вашей системе.
/usr/pgsql-9.1/bin
. Я должен использовать /usr/pgsql-9.1/bin/psql
вместо psql
потому что psql
в /usr/bin
относятся к другой версии.
– Abednego
01.01.2014, 07:24
Клиентский пакет, PostgreSQL91
, зависит от пакета сервера PostgreSQL91-Server
. Таким образом, у вас установлен клиент, но это не значение по умолчанию.
Пакеты RH используют механизм альтернативных альтернатив, заимствованные от Debian, чтобы контролировать какую программу выполняется. Вы можете выбрать версию для использования с:
sudo update-alternatives --config pgsql-psql
... хотя я не уверен, что это дело для более старой версии, которую вы используете.
Поочередно, вы можете установить путь путь
, чтобы сначала поставить новые двоичные файлы. Присоединяйтесь к .bash_profile
:
export PATH=/usr/pgsql-9.1/bin:$PATH
, а затем закрыть и снова откройте терминал.