Provided by: debconf-doc_1.5.58ubuntu2_all bug

НАЗВАНИЕ

       debconf - руководство разработчика

ОПИСАНИЕ

       Данное руководство помогает при разработке пакетов, использующих debconf.

       Предполагается,  что  вы  знакомы  с  debconf как пользователь, а также знакомы с основами
       создания пакетов debian.

       Это руководство начинается с описания двух новых  файлов,  которые  добавляются  в  пакеты
       debian,  если  они  используют  debconf.  Затем  объясняется  работа  протокола  debconf и
       описываются некоторые библиотеки, которые позволят вашим  программам  работать  с  ним.  В
       частности  обсуждаются  другие  сценарии  для сопровождения, которые обычно используются с
       debconf: сценарии postinst и postrm. Далее рассматриваются более сложные  темы,  например,
       общие  шаблоны debconf, отладка и некоторые основные приёмы и ловушки при программировании
       с debconf. Завершает руководство описание имеющихся недостатков debconf.

СЦЕНАРИЙ НАСТРОЙКИ

       Debconf добавляет дополнительный сценарий сопровождения, сценарий config,  который  служит
       для  настройки  сопровождающих  сценариев,  имеющихся в пакетах debian (postinst, preinst,
       postrm и prerm). Сценарий config отвечает за выдачу всех вопросов настройки пакета.

       Замечание: часто смущает тот факт,  что  dpkg  ссылается  на  запущенный  сценарий  пакета
       postinst  как  на  «настроечный»,  хотя  пакет, который использует debconf часто полностью
       настроен своим сценарием config ещё до того как postinst даже будет запущен. Такие дела.

       Как и postinst, сценарию config передаётся два параметра при запуске.  В  первом  задаётся
       действие,  которое  нужно  выполнить,  а во втором — версия установленного в данный момент
       пакета. Как и в  postinst,  вы  можете  применить  dpkg  --compare-versions  к  $2,  чтобы
       выполнить  данную  команду  только  при  обновлении  с  определённой  версии пакета и тому
       подобных операций.

       Сценарий config может быть запущен в трёх случаях:

       1      Во время предварительной настройки пакета из dpkg-preconfigure,  который  запускает
              сценарий config с параметрами «configure» и номером установленной версии.

       2      При  запуске postinst из пакета, debconf также попытается запустить сценарий config
              и передать те же параметры, что и в случае с предварительной настройкой пакета. Это
              необходимо,  так как пакет может не быть предварительно настроен, и сценарию config
              даётся ещё одна попытка отработать. Подробней смотрите в разделе ХАКИ.

       3      При повторной настройке пакета с  помощью  dpkg-reconfigure,  где  сценарий  config
              запускается с параметрами «reconfigure» и номером установленной версии.

       Заметим, что так как типичная установка или обновление с помощью apt попадают под случаи 1
       и 2, сценарий config обычно запускается дважды. Он ничего не должен делать во  второй  раз
       (отвечать   на   вопросы   второй  раз  подряд  раздражает),  и  определённо  должен  быть
       идемпотентен. К счастью, debconf избегает повторения вопросов по  умолчанию,  поэтому  это
       легко  достигается.

       Заметим,   что  сценарий  config  запускается  перед  распаковкой  пакета.  В  нём  должны
       использоваться только команды из пакетов первой  необходимости.  Единственная  зависимость
       пакета, которая будет удовлетворена до запуска сценария config — это сам debconf (возможно
       указать версию).

       Сценарию config ничего не нужно изменять в файловой системе. Он  должен  просто  проверить
       состояние  системы  и  задать вопросы, а debconf сохранит ответы, которые требуют действий
       позже из сценария postinst. И наоборот, сценарий postinst не должен  использовать  debconf
       для  задания  вопросов,  а вместо этого должен полагаться на ответы, полученные при работе
       сценария config.

ФАЙЛ TEMPLATES

       Пакету, использующему debconf, вероятно требуется задать некоторые  вопросы.  Эти  вопросы
       хранятся в форме шаблона в файле templates.

       Как  и  сценарий  config,  файл templates находится в секции control.tar.gz deb файла. Его
       формат похож на формат debian файла control; секции строф, разделённые  пустыми  строками,
       каждая строфа задана в RFC822-подобной форме:

         Template: foo/bar
         Type: string
         Default: foo
         Description: Это пример строки вопроса.
          Это её дополнительное описание.
          .
          Заметим что:
           - как и в описании пакета debian точка
             в отдельной строке начинает новый параграф.
           - для большого текста выполняется перенос на новую строку, но текст
             с двойным отступом выводится как есть,
             вы можете использовать это для показа списков
             как сделано здесь. Осторожно, так как
             перенос не выполняется, это очень плохо сказывается на слишком
             длинных строках. Используйте это для коротких элементов
             (поэтому это плохой пример).

         Template: foo/baz
         Type: boolean
         Description: Вроде всё просто?
          Это другой вопрос, логического типа.

       Несколько     рабочих     примеров     для     файлов     templates    можно    найти    в
       /var/lib/dpkg/info/debconf.templates и других файлах .templates в этом каталоге.

       Давайте рассмотрим каждое из полей по очереди..

       Template
              Название шаблона в поле «Template» обычно начинается с названия пакета. Далее можно
              использовать  что  угодно;  вы  можете  использовать простую схему как в предыдущем
              примере или настроить «подкаталоги», содержащие похожие вопросы.

       Type   Тип шаблона, который определяет какого вида будет показан элемент. Поддерживаются:

              string Поле ввода произвольных данных, в которое пользователь  может  ввести  любую
                     строку.

              password
                     Предлагает  пользователю  ввести  пароль.  Используйте с осторожностью; этот
                     пароль будет сохранён в базу данных debconf. Вероятно, вы должны удалить это
                     значение из базы как можно быстрее.

              boolean
                     Выбор true/false.

              select Выбор  одного  из  указанных  значений.  Значения  должны быть заданы в поле
                     «Choices». Разделителями значений могут быть запятые и пробелы:
                       Choices: да, нет, может_быть

              multiselect
                     Как и в типе данных select, выбор из списка, кроме  того,  что  пользователь
                     может выбрать сразу несколько значений из списка (или ни одного из них).

              note   Вместо  вопроса  как  такового,  этот  тип данных задаёт примечание, которое
                     может быть показано пользователю. Данный тип  должен  использоваться  только
                     для  важных  сообщений, которые пользователи обязательно должны увидеть, так
                     как  debconf  обязательно  сделает  так,  чтобы  пользователь  увидел   это;
                     установка  остановится,  пока  не  будет  нажата  клавиша.  Данный тип лучше
                     использовать только для предупреждений о серьёзных проблемах.

              error  Этот тип данных используется для сообщений  об  ошибках,  таких  как  ошибки
                     ввода  данных.  Debconf  покажет вопрос этого типа даже если приоритет самый
                     высокий и пользователь уже видел этот вопрос.

              title  Этот  тип  данных  используется  для  заголовков,  которые   устанавливаются
                     командой SETTITLE.

              text   Данный  тип данных может быть использован для показа частей текста, например
                     ярлыков, которые могут  использоваться  в  косметических  целях  отображения
                     некоторыми интерфейсами. Некоторые интерфейсы вообще не используют этот тип.
                     Пока нет общих принципов по использованию  его,  так  как  нет  интерфейсов,
                     которые поддерживают его хорошо. Может в будущем он будет вообще удалён.

       Default
              Поле  «Default»  указывает  debconf,  какое  должно быть значение по умолчанию. Для
              multiselect это может быть список значений, разделённых запятыми или пробелами, как
              в  поле  «Choices».  Для  select  —  это одно значение из списка. Для boolean — это
              «true» или «false», хотя может использоваться любая строка, и она игнорируется  для
              паролей.

              Не подумайте, что поле значения по умолчанию содержит «ответ» на вопрос, или что он
              может быть использован для замены ответа на вопрос. Это не так,  и  не  может  быть
              так,  он  только  предоставляет ответ по умолчанию при первом показе вопроса. Чтобы
              изменить значение по умолчанию на лету, используйте команду SET.

       Description
              Поле «Description» подобно полю описания в пакете Debian, имеет две части: короткое
              описание  и  расширенное  описание.  Заметим, что некоторые интерфейсы к debconf не
              отображают длинное описание, или  могут  показать  его,  только  если  пользователь
              попросит  показать  помощь.  Поэтому  короткое  описание должно отображать всю суть
              вопроса.

              Если вы не можете придумать длинного описания, то сначала  подумайте  ещё  немного.
              Напишите  в  debian-devel.  Попросите  помочь.  Возьмите урок по написанию! Длинное
              описание очень важно. Если после всего этого ничего не приходит в голову,  оставьте
              поле пустым. Нет смысла дублировать то, что уже написано в коротком описании.

              Текст  в расширенном описании будет переноситься по словам, если он не начинается с
              дополнительного пробельного  символа  (после  первого  обязательного  пробела).  Вы
              можете разбить его на параграфы поместив « .» в пустой строке между параграфами.

ВОПРОСЫ

       Вопрос  — это проиллюстрированный шаблон. Прося debconf показать вопрос, таким образом ваш
       сценарий config может взаимодействовать с  пользователем.  Когда  debconf  загружает  файл
       templates  (это  происходит  при  запуске  сценария config или postinst), он автоматически
       показывает вопрос каждого шаблона. На самом  деле  можно  показать  несколько  независимых
       вопросов из одного шаблона (с помощью команды REGISTER), но это требуется редко. Шаблоны —
       это  статические  данные  из  файла  templates,  а  вопросы  используются   для   хранения
       динамических  данных,  таких как имеющийся ответ на вопрос, видел ли пользователь уже этот
       вопрос и тому подобное. Помните об этом различии между шаблоном и вопросом,  но  не  стоит
       сильно забивать этим голову.

ОБЩИЕ ШАБЛОНЫ

       Фактически,  есть возможность иметь один шаблон и вопрос сразу для нескольких пакетов. Все
       пакеты могут предоставлять идентичную копию шаблона в своих файлах  templates.  Это  может
       быть  полезно,  если  набору  пакетов  требуется  задать один и тот же вопрос, а вы хотите
       побеспокоить пользователя только один раз. Общие шаблоны обычно помещаются в псевдокаталог
       shared/ в пространстве имён шаблонов debconf.

ПРОТОКОЛ DEBCONF

       Сценарии  config  взаимодействуют с debconf по протоколу debconf. Это простой однострочный
       протокол, похожий на основные протоколы интернета, типа  SMTP.  Сценарий  config  посылает
       debconf  команду,  записывая  эту  команду  в стандартный вывод. Затем, он может прочитать
       ответ debconf со стандартного ввода.

       Ответы debconf можно разделить на две части:  числовой  код  результата  (первое  слово  в
       ответе)  и необязательный расширенный код результата (оставшаяся часть ответа). В числовом
       коде значение 0 соответствует успешному выполнению, а другие числа указывают на различного
       вида неудачи. Подробней смотрите таблицу в политике Debian, раздел спецификации debconf.

       Расширенный  код  результата  имеет  любой  вид  и  никак не стандартизован, поэтому нужно
       игнорировать его и не пытаться использовать в своей программе  для  выяснения  что  делает
       debconf.  Исключение  составляют команды типа GET, которая создаёт значение для возврата в
       расширенном коде результата.

       Обычно  вы  будете  использовать  библиотеку,  которая  работает  на  низком  уровне   для
       установления связи с debconf и взаимодействия с ним.

       А теперь обсудим команды протокола. Это не полное описание, за ним обращайтесь к документу
       о политике Debian, раздел спецификации debconf.

       VERSION номер
              Обычно не нужно использовать эту команду. Она позволяет договориться  с  debconf  о
              том,  какая  версия  протокола должна быть использована. Текущая версия протокола —
              2.0, а версии  ветки  2.x  обратно  совместимы.  Вы  можете  указать  номер  версии
              протокола  и  debconf  вернёт  версию протокола в расширенном коде результата. Если
              указанная вами версия слишком стара, debconf вернёт числовой код 30.

       CAPB возможности
              You generally don't need to use this command. It exchanges with debconf a  list  of
              supported  capabilities  (separated  by  spaces).  Capabilities  that  both you and
              debconf support will be used, and debconf will reply with all the  capabilities  it
              supports.

              Если  среди  ваших  возможностей  будет  «escape»,  то debconf будет ожидать, что в
              посылаемых вами командах символы обратный слеш и новой строки экранированы (\\ и \n
              соответственно),  а  в  своих  ответах  будет  также  это  делать.  Это  может быть
              использовано, например, для подстановки многострочных строк  в  шаблонах,  или  для
              получения  многострочных  расширенных  описаний,  использующихся  в METAGET. В этом
              режиме вы должны сами экранировать входной текст (для этого вы можете  использовать
              команду  debconf-escape(1),  если  хотите),  а  библиотеки confmodule будут снимать
              экранирования в ответах за вас.

       SETTITLE вопрос
              Устанавливает  заголовок,  который  debconf  показывает   пользователю,   используя
              короткое описание шаблона указанного вопроса. Шаблон должен быть типа title. Обычно
              редко используется, так как debconf может автоматически генерировать  заголовок  на
              основе имени пакета.

              Установка  заголовка из шаблона означает, что они хранятся в том же месте что и все
              вопросы debconf, и их можно переводить на другие языки.

       TITLE строка
              Устанавливает  заголовок,  который  debconf  показывает   пользователю,   используя
              заданную  строку. Использование команды SETTITLE предпочтительно, так как позволяет
              переводить заголовок на другие языки.

       INPUT приоритет вопрос
              Просит debconf подготовить к показу вопрос пользователю. Вопрос не показывается  до
              тех  пор  пока  не  будет  дана  команда  GO;  это позволяет последовательно задать
              несколько команд INPUT для накопления набора вопросов, которые  могут  быть  заданы
              все разом на одном экране.

              Поле  приоритета  говорит  debconf  насколько  важен  вопрос, который будет показан
              пользователю. Значения приоритета:

              low    Очень простые элементы  со  значениями  по  умолчанию,  которые  работают  в
                     подавляющем большинстве случаев; только параноики увидят их.

              medium Обычные элементы с корректными значениями по умолчанию.

              high   Элементы, у которых нет приемлемых значений по умолчанию.

              critical
                     Элементы,  которые  вероятно  сломают  систему,  если не будет вмешательства
                     пользователя.

              Debconf  сам  решает  нужно  ли  вообще  показывать  вопрос,  основываясь  на  этом
              приоритете  и  том,  видел  ли  уже  пользователь  этот  вопрос  и  какой интерфейс
              используется для показа. Если вопрос не будет показан, debconf возвращает код 30.

       GO
              Указывает debconf показать накопленные вопросы (переданные ранее  командами  INPUT)
              пользователю.

              Если  поддерживается  возможность backup и пользователь потребовал вернуться на шаг
              назад, то debconf возвратит код 30.

       CLEAR  Очистить накопленные вопросы (из команд INPUT) и не показывать их.

       BEGINBLOCK

       ENDBLOCK
              Некоторые интерфейсы debconf могут показывать пользователю сразу несколько вопросов
              одновременно.  Может  быть  в  будущем  интерфейсы  даже  смогут группировать такие
              вопросы по блокам на экране. BEGINBLOCK и ENDBLOCK могут указываться вокруг  набора
              команд  INPUT, чтобы обозначить блоки вопросов (и блоки могут быть вложенными). Так
              как пока ни один интерфейс к debconf  не  поддерживает  их,  в  данный  момент  эти
              команды игнорируются.

       STOP   Эта  команда  указывает  debconf  на завершения взаимодействия с ним. Часто debconf
              может сам обнаружить завершение вашей программы и эта команда не обязательна.

       GET вопрос
              После отработки INPUT и GO для показа вопроса, вы можете использовать  эту  команду
              для  получения  значения  введённого  пользователем.  Значение  возвращается в виде
              расширенного кода результата.

       SET вопрос ответ
              Задаёт ответ на вопрос; это можно  использовать  для  замены  ответа  по  умолчанию
              чем-то, что ваша программа вычислила во время работы.

       RESET вопрос
              Сбрасывает  ответ на вопрос в значение по умолчанию (как указано в поле «Default» в
              шаблоне).

       SUBST вопрос ключ значение
              Вопросы могут  содержать  подстановки  в  полях  «Description»  и  «Choices»  (хотя
              использование  подстановок  в  полях  «Choices»  считается хаком; со временем будет
              разработан лучший способ). Эти подстановки выглядят  как  "${ключ}".  Когда  вопрос
              отображается,  подстановки  заменяются  на  нужные значения. Эта команда может быть
              использована для задания значения подстановки.  Это  полезно,  если  вам  требуется
              показать какое-то сообщение пользователю, которое нельзя однозначно записать в файл
              templates.

              Не пытайтесь использовать SUBST для замены ответа по умолчанию на  вопрос;  это  не
              сработает, так как для этого служит команда SET.

       FGET вопрос флаг
              Вопросы  могут  иметь связанные с ними флаги. Флаги могут иметь значение «true» или
              «false». Эта команда возвращает значение флага.

       FSET вопрос флаг значение
              Устанавливает значение флага вопроса. Значение должно быть или «true» или «false».

              Распространённым флагом является флаг «seen». Обычно он устанавливается только если
              пользователь  уже  видел  вопрос.  Debconf  обычно  показывает  только  те  вопросы
              пользователю, у которых флаг seen установлен в «false» (или если происходит процесс
              перенастройки  пакета). Иногда вам нужно чтобы пользователь увидел вопрос снова — в
              этом случае вы можете установить флаг seen  в  значение  «false»,  чтобы  заставить
              debconf показать вопрос ещё раз.

       METAGET вопрос поле
              Возвращает  значение  любого  поля  вопроса  из соответствующего шаблона (например,
              Description).

       REGISTER шаблон вопрос
              Создаёт новый вопрос, который привязывается к шаблону. По умолчанию, каждый  шаблон
              имеет  соответствующий  вопрос  с  тем  же именем. Однако, с шаблоном можно связать
              любое число вопросов, и это позволяет создать много таких вопросов.

       UNREGISTER вопрос
              Удаляет вопрос из базы данных.

       PURGE  Вызывайте эту команду из сценария  postrm  при  вычистке  пакета.  Она  удалит  все
              вопросы пакета из базы данных debconf.

       X_LOADTEMPLATEFILE /путь/к/templates [владелец]
              Это  расширение  загружает  указанный  файл  template  в  базу  данных  debconf. По
              умолчанию, владельцем  считается  пакет,  который  в  данный  момент  настраивается
              debconf.

       Вот простой пример протокола debconf в действии.

         INPUT medium debconf/frontend
         30 question skipped
         FSET debconf/frontend seen false
         0 false
         INPUT high debconf/frontend
         0 question will be asked
         GO
         [ Здесь debconf показывает вопрос пользователю. ]
         0 ok
         GET no/such/question
         10 no/such/question doesn't exist
         GET debconf/frontend
         0 Dialog

БИБЛИОТЕКИ

       Настройка  окружения для работы с debconf и общение с debconf по протоколу вручную требует
       слишком больших затрат, поэтому для этого  существуют  промежуточные  библиотеки,  которые
       освобождают человека от этой монотонной работы.

       Для   программирования   на   языке   оболочки   командной  строки  существует  библиотека
       /usr/share/debconf/confmodule, которую вы можете указать в  начале  сценария  оболочки,  и
       общаться  с  debconf  в  довольно естественной манере, используя команды debconf протокола
       записанные строчными буквами, которые начинаются с «db_» (то есть, «db_input» и  «db_go»).
       Подробней смотрите в confmodule(3).

       Программисты   на  perl  могут  использовать  модуль  Debconf::Client::ConfModule(3pm),  а
       программисты на python могут использовать модуль debconf.

       В последующих  примерах  сценариев  оболочки  руководства  будет  использована  библиотека
       /usr/share/debconf/confmodule. Вот пример сценария config, который задаёт вопрос с помощью
       этой библиотеки:

         #!/bin/sh
         set -e
         . /usr/share/debconf/confmodule
         db_set mypackage/reboot-now false
         db_input high mypackage/reboot-now || true
         db_go || true

       Заметим, что использование "|| true" предотвращает сценарий  от  завершения  работы,  если
       debconf  решит,  что  не  может  показать вопрос, или когда пользователь решит вернуться к
       предыдущему вопросу. В таких ситуациях debconf возвращает ненулевой код  возврата,  и  так
       как в сценарии оболочки указана set -e, неотловленный код выхода прервёт его работу.

       А  вот  соответствующий  сценарий  postinst,  который использует пользовательский ответ на
       вопрос, должна ли система быть перезагружена (слегка абсурдный пример..):

         #!/bin/sh
         set -e
         . /usr/share/debconf/confmodule
         db_get mypackage/reboot-now
         if [ "$RET" = true ]; then
            shutdown -r now
         fi

       Заметим, что используемая переменная $RET получает расширенный  код  возврата  от  команды
       GET, который содержит ответ пользователя на вопрос.

СЦЕНАРИЙ POSTINST

       В  последнем разделе был приведён пример сценария postinst, который использует debconf для
       получения ответа на вопрос и выполняет соответствующие действия. Есть  несколько  вещей  о
       которых нужно помнить при написании сценариев postinst, использующих debconf:

       *      Не задавайте вопросов из сценария postinst. Вопросы должен задавать сценарий config
              с помощью debconf, для того чтобы работал механизм предварительной настройки.

       *      Всегда включайте /usr/share/debconf/confmodule в самом  начале  сценария  postinst,
              даже  если  не  будет использоваться никаких команд db_*. Это нужно для того, чтобы
              дать шанс запуститься сценарию config (подробней смотрите в разделе ХАКИ).

       *      Избегайте вывода чего-либо в stdout из сценария postinst, так как это debconf может
              неправильно   понять   и   вообще,   сценарий   postinst  не  должен  быть  слишком
              разговорчивым. Если очень нужно — выводите в stderr.

       *      Если сценарий postinst запускается в  режиме  демона,  убедитесь,  что  вы  послали
              debconf  команду  STOP  в  конце  работы, так как debconf не сможет отловить момент
              когда postinst закончил с ним работать.

       *      Пишите сценарий postinst так, чтобы он принимал первым параметром «reconfigure». Он
              может  трактовать  его  как «configure». Это будет использовано в следующих версиях
              debconf, чтобы указать сценариям postinst когда они должны выполнять перенастройку.

ДРУГИЕ СЦЕНАРИИ

       Кроме сценариев config и  postinst,  вы  можете  использовать  debconf  в  любом  сценарии
       сопровождения  пакета.  Наиболее  часто  вы будете использовать debconf в сценарии postrm,
       чтобы вызвать команду PURGE при удалении пакета для удаления всех записей о пакете из базы
       данных debconf (кстати, это настраивается автоматически с помощью dh_installdebconf(1)).

       Также  debconf  может  быть использован в сценарии postrm при вычистке пакета чтобы задать
       вопрос об удалении чего-либо. Или может быть по какой-то причине вам  может  потребоваться
       использовать  его в preinst или prerm. Везде он будет работать, хотя это вероятно приведёт
       к выдаче одинаковых вопросов и  реакции  на  ответы  в  программе,  а  не  к  двум  разным
       действиям, как это происходит со сценариями config и postinst.

       Заметим,  что  если  ваш  пакет  использует  debconf  только  в сценарии postrm, вы должны
       добавить вызов  /usr/share/debconf/confmodule  в  начало  сценария  postinst,  чтобы  дать
       debconf  шанс  загрузить файл templates в свою базу данных. Затем templates будет доступен
       во время вычистке пакета.

       Также вы можете использовать debconf просто  в  работе  программ.  Но  не  забывайте,  что
       debconf не предназначен для этого, и не должен использоваться как своеобразный реестр. Это
       всё-таки unix, и настройки программ хранятся в файлах в каталоге /etc,  а  не  в  какой-то
       мутной  базе  данных  debconf (которая в конечном счёте просто кэш и может сломаться). Так
       что тридцать раз подумайте перед тем как использовать debconf в простых программах.

       Есть ситуации когда это имеет смысл, например в программе  apt-setup,  которая  использует
       debconf   для  того  чтобы  пользователь  завершил  процесс  установки  debian  в  похожем
       интерфейсе, и сразу же применяет эти ответы для  настройки  файла  sources.list  программы
       apt.

ЛОКАЛИЗАЦИЯ

       Debconf   поддерживает   локализацию   файлов   templates.   Это  достигается  добавлением
       дополнительных полей с переведённым текстом. Любые поля можно переводить.  Например,  есть
       желание перевести описание на испанский. Просто создайте поле с именем «Description-es», в
       котором есть перевод.  Если  переведённое  поле  недоступно,  debconf  использует  обычный
       английский вариант.

       Помимо  поля  «Description»,  вы  можете  перевести  поле  «Choices» из шаблона select или
       multiselect. Убедитесь, что переведённые значения в списке расположены в  том  же  порядке
       что  и в основном поле «Choices». Вам не нужно переводить поле «Default» из вопроса select
       или multiselect, ответ на вопрос будет автоматически возвращён на английский.

       Вы обнаружите, что для облегчения управления  переводами  лучше  хранить  их  в  отдельных
       файлах;   один   файл   на  перевод.  Раньше  для  управления  файлами  debian/template.ll
       использовались программы debconf-getlang(1) и debconf-mergetemplate(1). Теперь эту функцию
       выполняет  пакет  po-debconf(7),  который  позволяет  работать  с переводами debconf в .po
       файлах как  с  любыми  другими  переводами.  Ваши  переводчики  будут  благодарны  вам  за
       использование этого нового усовершенствованного механизма.

       Подробней  о po-debconf смотрите в его справочной странице. Если вы используете debhelper,
       переведите его в po-debconf просто  запустив  один  раз  команду  debconf-gettextize(1)  и
       добавьте зависимость в Build-Dependency от po-debconf и от debhelper (>= 4.1.13).

СОБЕРЁМ ВСЁ ВМЕСТЕ

       Итак,  у вас есть сценарий config, файл templates, сценарий postinst, использующие debconf
       и так далее. Поместить все эти части в  пакет  debian  несложно.  Вы  можете  сделать  это
       вручную  или  с  помощью  dh_installdebconf(1),  которая  объединяет переведённые шаблоны,
       копирует файлы в нужные места, и даже  генерирует  вызов  PURGE,  который  должен  быть  в
       сценарии  postrm.  Убедитесь,  что  ваш  пакет  зависит от debconf (>= 0.5), так как более
       ранние версии несовместимы с всем описанным в руководстве. Всё.

       Да, за исключением тестирования, отладки  и  реального  использования  debconf  для  более
       интересных вещей чем простое задание вопросов. Об этом читайте далее..

ОТЛАДКА

       Итак,  у  вас  есть  пакет,  который  предположительно использует debconf, но он не совсем
       работает. Может быть debconf не только задаёт вопросы при настройке. Или может быть что-то
       странное  случается;  он  крутится  в  каком-то  вечном цикле или хуже. К счастью, debconf
       обладает множеством средств отладки.

       DEBCONF_DEBUG
              Наипервейшая вещь — это переменная окружения DEBCONF_DEBUG. Если вы сделаете export
              DEBCONF_DEBUG=developer,  то debconf будет выводить в stderr дамп протокола debconf
              при работе. Это выглядит как-то так(сразу видно опечатку):

               debconf (developer): <-- input high debconf/frontand
               debconf (developer): --> 10 "debconf/frontand" doesn't exist
               debconf (developer): <-- go
               debconf (developer): --> 0 ok

              Для отладки довольно полезно  использовать  интерфейс  debconf  readline(по  мнению
              автора), поскольку вопросы не мешают и весь отладочный вывод легко сохранить.

       DEBCONF_C_VALUES
              Если  значение  данной переменной окружения равно «true», то интерфейсная программа
              будет показывать значения шаблонов Choices-C (если есть)  выбора  и  множественного
              выбора, вместо описательных значений.

       debconf-communicate
              Другим  полезным  инструментом  является  программа  debconf-communicate(1). Просто
              запустите  её  и  вы  сможете  интерактивно  вводить  команды   протокола   debconf
              непосредственно в debconf. Это отличный способ попробовать команды на лету.

       debconf-show
              Если  пользователь  сообщил  о  проблеме, можно использовать debconf-show(1), чтобы
              скопировать все вопросы пакета, показать их ответы и  узнать  какие  из  них  видел
              пользователь.

       .debconfrc
              Чтобы  избежать  утомительного цикла сборка/установка/отладка, можно загрузить файл
              templates с помощью debconf-loadtemplate(1) и запустить сценарий config  вручную  с
              помощью   команды   debconf(1).   Однако,   вам   по   прежнему   требуются   права
              суперпользователя? Не очень здорово. И в идеале вы хотели бы увидеть  как  проходит
              новая установка, с чистой базой данных debconf.

              Оказывается,  если вы настроите файл ~/.debconfrc для обычного пользователя, указав
              в нём личный config.dat и template.dat, то  сможете  загружать  файлы  templates  и
              запускать сценарий config как хочется, без полномочий суперпользователя. Если нужно
              ещё раз запуститься с чистой базой данных, просто удалите файлы *.dat.

              Подробности  настройки  смотрите   в   debconf.conf(5),   и   заметим,   что   файл
              /etc/debconf.conf отлично подойдёт как шаблон для личного файла ~/.debconfrc.

УГЛУБЛЁННОЕ ПРОГРАММИРОВАНИЕ С DEBCONF

   Работа с файлами настройки
       Многие  из  вас  хотели  бы  использовать debconf для управления файлами настройки пакета.
       Возможно в файлах настройки недостаточно настроек по умолчанию  и  поэтому  вы  бы  хотели
       использовать  debconf  для опроса пользователя и основываясь на его ответах создавать файл
       настройки. Кажется, что этого легко достичь, но когда вы задумаетесь  об  обновлении,  или
       когда кто-то ещё изменит файл настройки, созданный вами и про dpkg-reconfigure и ...

       Есть  много  способов  сделать это и большинство из них неправильные, а вы будете получать
       раздражающие отчёты об  ошибках.  Есть  один  правильный  путь  достижения  этого.  В  нём
       предполагается,  что  ваш  файл  настройки  состоит  из  простого  набора  устанавливаемых
       переменных оболочки с комментариями, и поэтому вы можете просто  выполнить  файл  для  его
       «загрузки». Если у вас более сложный формат, чтение (и запись) становятся более сложными.

       Ваш сценарий config будет выглядеть так:

        #!/bin/sh
        CONFIGFILE=/etc/foo.conf
        set -e
        . /usr/share/debconf/confmodule

        # Загрузить файл настройки, если он существует.
        if [ -e $CONFIGFILE ]; then
            . $CONFIGFILE || true

            # Сохранить значения из файла настройки в
            # базу данных debconf.
            db_set mypackage/foo "$FOO"
            db_set mypackage/bar "$BAR"
        fi

        # Задать вопросы.
        db_input medium mypackage/foo || true
        db_input medium mypackage/bar || true
        db_go || true

       А сценарий postinst будет выглядеть так:

        #!/bin/sh
        CONFIGFILE=/etc/foo.conf
        set -e
        . /usr/share/debconf/confmodule

        # Сгенерировать файл настройки, если он не существует.
        # Или скопировать из файла шаблона
        # откуда-то ещё.
        if [ ! -e $CONFIGFILE ]; then
            echo "# Config file for my package" > $CONFIGFILE
            echo "FOO=" >> $CONFIGFILE
            echo "BAR=" >> $CONFIGFILE
        fi

        # Выполнить подстановку значений из базы данных debconf.
        # Здесь явно возможна оптимизация.
        # Команда cp перед sed проверяет, что мы не испортили
        # права доступа и владельца файла настройки.
        db_get mypackage/foo
        FOO="$RET"
        db_get mypackage/bar
        BAR="$RET"
        cp -a -f $CONFIGFILE $CONFIGFILE.tmp

        # Если администратор удалил или закомментировал какие-то переменные, но
        # после задал их через debconf, добавим(пересоздадим) их в файле
        # настройки.
        test -z "$FOO" || grep -Eq '^ *FOO=' $CONFIGFILE || \
            echo "FOO=" >> $CONFIGFILE
        test -z "$BAR" || grep -Eq '^ *BAR=' $CONFIGFILE || \
            echo "BAR=" >> $CONFIGFILE

        sed -e "s/^ *FOO=.*/FOO=\"$FOO\"/" \
            -e "s/^ *BAR=.*/BAR=\"$BAR\"/" \
            < $CONFIGFILE > $CONFIGFILE.tmp
        mv -f $CONFIGFILE.tmp $CONFIGFILE

       Рассмотрим  как  эти  два  сценария  обрабатывают  все  возможные  ситуации. При начальной
       установке сценарий config задаёт вопросы и новый  файл  настройки  генерируется  сценарием
       postinst.  При  обновлении  или  перенастройке  файл  настройки  читается  и  его значения
       используются для изменения значений в базе данных debconf,  поэтому  значения,  изменённые
       администратором,  не теряются. Вопросы задаются снова (могут показываться, а могут и нет).
       Затем сценарий postinst выполняет  подстановку  значений  обратно  в  файл  настройки,  не
       изменяя всего остального.

   Позволить пользователю возвращаться назад
       Некоторые  вещи  ещё  сильнее  разочаровывают при использовании систем типа debconf: после
       заданного вопроса и ответа на него, переходишь  к  другому  экрану  с  новым  вопросом,  и
       отвечая  понимаешь,  что  совершил ошибку в последнем вопросе и хочешь вернуться обратно и
       обнаруживаешь, что не можешь сделать этого.

       Так как debconf управляется вашим сценарием  config,  он  не  может  прыгнуть  обратно  на
       предыдущий  вопрос  сам,  но  с  небольшой вашей помощью, он сможет выполнить этот подвиг.
       Первый шаг —  в  сценарии  config  дать  понять  debconf,  что  сценарий  config  способен
       обрабатывать  нажатие  кнопки  назад  пользователем.  Для  этого используйте команду CAPB,
       передав backup в качестве параметра.

       Затем, после каждой  команды  GO  вы  должны  выполнять  тест,  чтобы  увидеть  просил  ли
       пользователь   вернуться  назад  (debconf  возвратит  код  30),  и,  если  это  произошло,
       возвратиться к предыдущему вопросу.

       Есть несколько способов написания управляющих структур в вашей программе для возвращения к
       предыдущему  вопросу  при  необходимости. Вы можете написать код, использующий кучу команд
       перехода goto. Или вы  можете  создать  несколько  функций  и  использовать  рекурсию.  Но
       возможно  самым  понятным  и  простым  является  создание  конечного  автомата. Вот скелет
       конечного автомата, который можно заполнить и расширить.

        #!/bin/sh
        set -e
        . /usr/share/debconf/confmodule
        db_capb backup

        STATE=1
        while true; do
            case "$STATE" in
            1)
                 # Два несвязных вопроса.
                 db_input medium my/question || true
                 db_input medium my/other_question || true
            ;;
            2)
                 # Задавать этот вопрос, только если
                 # на первый был получен
                 # положительный ответ.
                 db_get my/question
                 if [ "$RET" = "true" ]; then
                      db_input medium my/dep_question || true
                 fi
            ;;
            *)
                 # Действие по умолчанию возникает, когда $STATE больше чем последнее
                 # введённое состояние и прерывает цикл. Для
                 # этого требуется, чтобы состояния были пронумерованы последовательно с 1
                 # без перерывов, так как в этом случае возникает событие по умолчанию
                 break # выход из обёртывающего цикла "while"
            ;;
            esac

            if db_go; then
                 STATE=$(($STATE + 1))
            else
                 STATE=$(($STATE - 1))
            fi
        done

        if [ $STATE -eq 0 ]; then
            # Пользователь хочет выйти из первого вопроса.
            # Это проблематичный случай. Обычная установка
            # пакетов с помощью dpkg и apt не даёт
            # вернуться к вопросам между пакетами как здесь написано,
            # поэтому завершить работу, оставив пакет ненастроенным,
            # вероятно, лучший путь обработки этой ситуации.
            exit 10
        fi

       Заметим, что если ваш сценарий config задаёт несколько несвязных между собой вопросов,  то
       конечный  автомат  не  нужен.  Просто задайте их все и GO; debconf покажет их все на одном
       экране, и пользователю не нужно возвращаться назад.

   Предотвращение бесконечных циклов
       Это может произойти с debconf, если в сценарии config есть цикл. Предположим,  вы  задаёте
       вопрос и проверяете ответ, и всё это в цикле пока ответ не станет правильным:

        ok=”
        do while [ ! "$ok" ];
            db_input low foo/bar || true
            db_go || true
            db_get foo/bar
            if [ "$RET" ]; then
                 ok=1
            fi
        done

       На  первый  взгляд всё выглядит хорошо. Но посмотрим что произойдёт, если значение foo/bar
       будет "" в начале цикла, а пользователь установил приоритет на высокий, или использует  не
       интерактивный  интерфейс,  и поэтому вопрос на самом деле задан не будет. Значение foo/bar
       не изменяется в db_input, и тест не проходит и повторяется. И всё зацикливается …

       Одним вариантом исправления  является  задание  значения  foo/bar  перед  входом  в  цикл.
       Например,  если  значение  по  умолчанию  foo/bar  равно «1», то вы можете выполнить RESET
       foo/bar перед входом в цикл.

       В другом варианте можно проверить код завершения команды  INPUT.  Если  он  равен  30,  то
       пользователю вопрос показан не был, и вы должны прервать цикл.

   Выбор из похожих пакетов
       Иногда  может  выполняться  установка  похожих по функциональности пакетов, и вы хотели бы
       предложить  пользователю  выбрать  пакет,  который  должен  использоваться  по  умолчанию.
       Примером таких наборов могут быть оконные менеджеры или файлы словарей ispell.

       Хотя  можно  для  каждого  пакета  задавать  простой  вопрос  «Использовать  этот пакет по
       умолчанию?», но это приведёт к большому числу повторяющихся вопросов, если устанавливается
       несколько  пакетов.  С  помощью  debconf  возможно создать список всех пакетов и позволить
       пользователю сделать из него выбор. Посмотрим как это делается.

       Сделайте так, чтобы все пакеты в наборе использовали общий шаблон. Например:

        Template: shared/window-manager
        Type: select
        Choices: ${choices}
        Description: Выбор оконного менеджера по умолчанию.
         Определяет выбранный оконный менеджер, который запускается
         по умолчанию при запуске X.

       Каждый пакет должен содержать копию  этого  шаблона.  Также  нужно  включить  код  в  свой
       сценарий config, примерно такой:

        db_metaget shared/window-manager owners
        OWNERS=$RET
        db_metaget shared/window-manager choices
        CHOICES=$RET

        if [ "$OWNERS" != "$CHOICES" ]; then
            db_subst shared/window-manager choices $OWNERS
            db_fset shared/window-manager seen false
        fi

        db_input medium shared/window-manager || true
        db_go || true

       Объяснение.  Во  время  запуска  сценария  config,  debconf  уже  прочитал все шаблоны для
       устанавливаемых пакетов. Так как эти пакеты используют общий  вопрос,  debconf  записывает
       этот факт в поле владельцев. По странному совпадению формат поля владельцев такой же как и
       у поля выбора (запятая и пробел являются разделителями в списке значений).

       Команда METAGET может использоваться для получения списка владельцев и списка выбора. Если
       они  различаются,  то  это  значит,  что  был установлен новый пакет. Поэтому используется
       команда SUBST для замены списка выбора на список владельцев и задаётся вопрос.

       При удалении пакета вы вероятно хотите  проверить  не  является  этот  пакет  выбранным  в
       списке, и если так, то попросить пользователя выбрать другой пакет по умолчанию на замену.

       Это  можно  выполнить  добавив  следующее  в  сценарии prerm всех похожих пакетов (заменив
       <package> именем пакета):

        if [ -e /usr/share/debconf/confmodule ]; then
            . /usr/share/debconf/confmodule
            # больше не задавать этот вопрос.
            db_unregister shared/window-manager

            # Проверить, что общий вопрос ещё существует.
            if db_get shared/window-manager; then
                 db_metaget shared/window-manager owners
                 db_subst shared/window-manager choices $RET
                 db_metaget shared/window-manager value
                 if [ "<package>" = "$RET" ] ; then
                      db_fset shared/window-manager seen false
                      db_input high shared/window-manager || true
                      db_go || true
                 fi

                 # Теперь сделать тоже что делает сценарий postinst
                 # для обновления символической ссылки оконного менеджера.
            fi
        fi

ХАКИ

       В настоящее время debconf не полностью интегрирован с dpkg  (но  я  хочу  изменить  это  в
       будущем), и поэтому сейчас вызывается для некоторых неприятных хаков.

       Худшие  из  них  требуют  запуска сценария config. Для этого в настоящий момент приходится
       запускать сценарий config во время предварительной настройки пакета.  Также,  при  запуске
       сценария  postinst,  снова  запускается  debconf.  Debconf  понимает,  что  запускается из
       сценария postinst и поэтому останавливается и запускает  сценарий  config.  Это  работает,
       только  если  ваш  postinst  загружает хотя бы одну из библиотек debconf, поэтому postinst
       всегда делает это. Мы надеемся вернуться к этому позже добавив явную поддержку в dpkg  для
       debconf. Программа debconf(1) — это шаг в данном направлении.

       Похожий  хак  —  запуск  debconf  когда  сценарии  config,  postinst  или другие программы
       используют его при запуске. Не смотря ни на что, они ожидают что будут  сразу  общаться  с
       debconf. Сейчас это выполняется, так что когда такой сценарий загружает библиотеку debconf
       (типа /usr/share/debconf/confmodule), а debconf ещё не запущен, он  запускается,  и  новая
       копия  сценария  выполняется  заново.  Заметный  результат  в том, что вам нужно указывать
       строку загрузки библиотеки debconf как можно ближе к началу сценария, или могут  случиться
       непонятные  вещи.  Мы  надеемся  вернуться  к этой проблеме позже изменив вызов debconf, и
       превратить его в что-то подобное отдельного демона.

       Сравнимо с хаком и то, как debconf выясняет какие  файл  шаблонов  загружены  и  когда  их
       загружать.  Когда  сценарии  config, preinst и postinst вызывают debconf, он автоматически
       выясняет где файл templates и загружает его. Отдельные  программы,  использующие  debconf,
       заставляют           debconf           искать           файл           шаблонов          в
       /usr/share/debconf/templates/имя_программы.templates. И  если  postrm  хочет  использовать
       debconf  при  вычистке,  шаблоны  будут  недоступны  если  только у debconf не будет шанса
       загрузить их в postinst. Не неприятно, но неизбежно. Хотя в  будущем  некоторые  из  таких
       программ смогут использовать debconf-loadtemplate вручную.

       Исторически   сложившееся   поведение  /usr/share/debconf/confmodule  играть  с  файловыми
       дескрипторами и устанавливать fd #3 через который  происходит  общение  с  debconf,  может
       вызывать  весь  набор  проблем  при  запуске  из  postinst демона, так как демон завершает
       общение с debconf, а debconf не может определить когда завершился сценарий.  Команда  STOP
       помогает  обойти  это.  В  будущем, мы рассмотрим создание связи с debconf через сокет или
       другой механизм отличный от stdio.

       Debconf устанавливает DEBCONF_RECONFIGURE=1 перед  запуском  сценариев  postinst,  поэтому
       сценарий   postinst,  которому  требуется  избежать  некоторой  затратной  операции  перед
       перенастройкой, может проверить наличие  этой  переменной.  Это  хак,  так  как  правильно
       сделать  это — передать $1 = «reconfigure», но этого делать нельзя, так как будут работать
       неправильно все сценарии postinst, использующие debconf. Разработан план перехода на приём
       сценариями  postinst  значения  «reconfigure»,  и  как  только  все  сделают это, начнётся
       передача этого параметра.

СМОТРИТЕ ТАКЖЕ

       В debconf(7) содержится руководство пользователя debconf.

       Описание  debconf  в   политике   debian   является   спецификацией   протокола   debconf.
       /usr/share/doc/debian-policy/debconf_specification.txt.gz

       debconf.conf(5)  содержит  много полезной информации, включая описание среды хранения базы
       данных.

АВТОР

       Joey Hess <joeyh@debian.org>

                                                                                 DEBCONF-DEVEL(7)