CentOS 5: Моя серверная версия Postgresql отличается с моим psql клиентом.Что мне делать?

[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.

2
31.12.2013, 15:38
3 ответа

psql клиент находится в отдельном пакете с psql сервера. Это обычно звонило postgresql-клиенту.

0
27.01.2020, 21:57

Вероятно, что у Вас есть больше чем одна версия 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 находятся там в Вашей системе.

4
27.01.2020, 21:57
  • 1
    Корректный. В моем случае это расположено в /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

, а затем закрыть и снова откройте терминал.

1
27.01.2020, 21:57

Теги

Похожие вопросы