Каждый раз, когда необходимо получить доступ к ssh серверу на порте не по умолчанию или с другим именем пользователя, можно определить псевдоним в ~/.ssh/config
.
Host mysvn
HostName server.com
Port 20000
User jm
Затем выполненный svn co svn+ssh://mysvn/home/svn/proj1
.
[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.
for i in ... ; do echo i ; done
цикл в busybox версии 'удара' вызовет busybox n времена, 1 на эхо, тогда как в ударе эхо было бы встроено). Попытайтесь действительно трудно поместить только 1 вызов в любую подкоманду, чтобы не иметь несколько вызов busybox (каждый с большими издержками).set -x
помогает найти их. – Olivier Dulac 09.01.2013, 10:03echo
зависит от параметра компиляции (ENABLE_FEATURE_SH_NOFORK
), который я думаю, делает его быстрее, но багги в угловых случаях (прерывания, эффекты специального builtins). попытка – Gilles 'SO- stop being evil' 09.01.2013, 12:58