---
description: 'Хитрости с файлами pkg-*'
next: books/porters-handbook/testing
params:
  path: /books/porters-handbook/pkg-files/
prev: books/porters-handbook/plist
showBookMenu: 'true'
tags: ["pkg", "pkg-message", "UCL", "pkg-install", "pkg-deinstall"]
title: 'Глава 9. Файлы pkg-*'
weight: 9
---

[[pkg-files]]
= pkg-*
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 9
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/porters-handbook/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

Есть несколько приёмов работы с файлами [.filename]#pkg-*#, которые мы ещё не описали, но они иногда могут быть очень кстати.

[[porting-message]]
== pkg-message

Если вам нужно вывести сообщение для человека, устанавливающего приложение, то вы можете поместить сообщение в файл [.filename]#pkg-message#. Эта возможность часто оказывается полезной для вывода дополнительных шагов установки, которые нужно предпринять после выполнения команды `pkg install`, или для вывода информации о лицензировании.

[IMPORTANT]
====
* Файл [.filename]#pkg-message# должен содержать только информацию, _критически важную_ для настройки и работы в FreeBSD, а также уникальную для данного порта.
* Информация по настройке должна отображаться только при первоначальной установке. Инструкции по обновлению должны показываться только при обновлении с соответствующей версии.
* Не обрамляйте сообщения ни пробелами, ни строками символов (такими как `----------`, `**********` или `==========`). Оставьте форматирование man:pkg[8].
* Коммиттеры имеют полное право ограничивать существующие сообщения диапазонами установки или обновления, используя спецификации формата UCL.
* Пожалуйста, убедитесь, что используете соответствующие инструменты для управления службами.
** Используйте `service имя start` для запуска службы вместо `/usr/local/etc/rc.d/имя start`
** Используйте `sysrc name_enable=YES` для изменения параметров в rc.conf

====

pkg-message поддерживает два формата:

raw::
Обычный текстовый файл. Его сообщение отображается только при установке.

UCL::
Если файл начинается с символа "`[`", то он считается файлом в формате UCL. Формат UCL описан на странице https://github.com/vstakhov/libucl[libucl's GitHub page].

[NOTE]
====
Не добавляйте запись для [.filename]#pkg-message# в [.filename]#pkg-plist#.
====

[[porting-message-ucl]]
=== UCL в pkg-message

Формат следующий. Это должен быть массив объектов. Сами объекты могут содержать следующие ключевые слова:

`message`::
Отображаемое сообщение. Этот ключевой параметр является обязательным.

`type`::
Когда сообщение должно быть отображено.

`maximum_version`::
Только если `type` имеет значение `upgrade`. Отображается, если обновление выполняется с версии строго ниже указанной.

`minimum_version`::
Только если `type` имеет значение `upgrade`. Отображается, если обновление выполняется с версии, строго большей, чем указанная.

Ключевые слова `maximum_version` и `minimum_version` можно комбинировать.

Ключевое слово `type` может иметь три значения:

`install`::
Сообщение должно отображаться только при установке пакета.

`remove`::
Сообщение должно отображаться только при удалении пакета.

`upgrade`::
сообщение должно отображаться только во время обновления пакета.

[IMPORTANT]
====
Для сохранения совместимости с файлами [.filename]#pkg-message#, не использующими UCL, первая строка UCL [.filename]#pkg-message# _ДОЛЖНА быть_ одиночным символом "`[`", а последняя строка _ДОЛЖНА быть_ одиночным символом "`]`".
====

[[porting-message-ucl-short-ex]]
.Короткие строки UCL
[example]
====

Сообщение ограничено двойными кавычками `"`, это используется для простых однострочных строк:

[.programlisting]
....
[
{ type: install
  message: "Simple message"
}
]
....

====

[[porting-message-ucl-multiline-ex]]
.Многострочные строки UCL
[example]
====

Многострочные строки используют стандартную нотацию heredoc. Разделитель многострочной строки _должен_ начинаться сразу после символов `<<` без пробелов и _должен_ состоять только из заглавных букв. Чтобы завершить многострочную строку, добавьте строку-разделитель на отдельной строке без пробелов. Сообщение из раздела crossref:pkg-files[porting-message-ucl-short-ex,Короткие строки UCL] может быть записано как:

[.programlisting]
....
[
{ type: install
  message: <<EOM
Simple message
EOM
}
]
....

====

[[porting-message-ucl-ex2]]
.Показать сообщение при установке/удалении
[example]
====

Когда сообщение нужно отображать только при установке или удалении, укажите тип:

[.programlisting]
....
[
{
  type: remove
  message: "package being removed."
}
{ type: install, message: "package being installed."}
]
....

====

[[porting-message-ucl-ex3]]
.Показать сообщение при обновлении
[example]
====

При обновлении порта отображаемое сообщение может быть ещё более адаптировано к потребностям порта.

[.programlisting]
....
[
{
  type: upgrade
  message: "Package is being upgraded."
}
{
  type: upgrade
  maximum_version: "1.0"
  message: "Upgrading from before 1.0 need to do this."
}
{
  type: upgrade
  minimum_version: "1.0"
  message: "Upgrading from after 1.0 should do that."
}
{
  type: upgrade
  maximum_version: "3.0"
  minimum_version: "1.0"
  message: "Upgrading from > 1.0 and < 3.0 remove that file."
}
]
....

[IMPORTANT]
****
При отображении сообщения во время обновления важно ограничить случаи, когда оно показывается пользователю. Чаще всего это делается с помощью `maximum_version`, чтобы ограничить его использование обновлениями до определённой версии, когда требуется выполнить конкретное действие.
****

====

[[pkg-install]]
== pkg-install, pkg-pre-install и pkg-post-install

Если порту необходимо выполнять команды при установке бинарного пакета с помощью `pkg add` или `pkg install`, используйте [.filename]#pkg-install#. Он запускается дважды через `pkg`: первый раз как `${SH} pkg-install ${PKGNAME} PRE-INSTALL` перед установкой пакета и второй раз как `${SH} pkg-install ${PKGNAME} POST-INSTALL` после его установки. Переменная `$2` может быть проверена, чтобы определить, в каком режиме выполняется скрипт. Переменная окружения `PKG_PREFIX` устанавливается равной имени каталога установки пакета.

Если используется [.filename]#pkg-pre-install# или [.filename]#pkg-post-install#, скрипт выполняется только один раз (до или после установки пакета), с единственным аргументом `${PKGNAME}`. Использование [.filename]#pkg-pre-install.lua# или [.filename]#pkg-post-install.lua# запускает скрипт на Lua вместо shell-скрипта. Скрипты на Lua, выполняемые `pkg`, предоставляют некоторые расширения и несколько ограничений, которые описаны в man:pkg-lua-script[5].

[NOTE]
====
Использование [.filename]#pkg-pre-install# (или [.filename]#pkg-pre-install.lua#) и [.filename]#pkg-post-install# (или [.filename]#pkg-post-install.lua#) предпочтительнее, чем использование [.filename]#pkg-install#.
====

Эти скрипты автоматически добавляются в список упаковки.

[IMPORTANT]
====
Эти скрипты предназначены для упрощения настройки пакетов после установки. Они _не должны_ использоваться для запуска служб, остановки служб или выполнения любых других команд, которые изменяют текущую работающую систему.
====

[[pkg-deinstall]]
== pkg-deinstall, pkg-pre-deinstall и pkg-post-deinstall

Эти скрипты выполняются при удалении пакета.

Скрипт [.filename]#pkg-deinstall# выполняется дважды командой `pkg delete`. Первый раз как `${SH} pkg-deinstall ${PKGNAME} DEINSTALL` до удаления порта и второй раз как `${SH} pkg-deinstall ${PKGNAME} POST-DEINSTALL` после удаления порта. Переменная `$2` может быть проверена для определения режима, в котором выполняется скрипт. Переменная окружения `PKG_PREFIX` устанавливается в каталог установки пакета.

Если используется [.filename]#pkg-pre-deinstall# или [.filename]#pkg-post-deinstall#, скрипт выполняется только один раз (до или после удаления пакета) с единственным аргументом `${PKGNAME}`. Использование [.filename]#pkg-pre-deinstall.lua# или [.filename]#pkg-post-deinstall.lua# запустит скрипт на Lua вместо shell-скрипта. Скрипты на Lua, выполняемые `pkg`, предоставляют некоторые расширения и ограничения, которые описаны в man:pkg-lua-script[5].

[NOTE]
====
Использование [.filename]#pkg-pre-deinstall# (или [.filename]#pkg-pre-deinstall.lua#) и [.filename]#pkg-post-deinstall# (или [.filename]#pkg-post-deinstall.lua#) предпочтительнее, чем использование [.filename]#pkg-deinstall#.
====

Эти скрипты автоматически добавляются в список упаковки.

[IMPORTANT]
====
Эти скрипты предназначены для упрощения очистки после удаления пакетов. Они _не должны_ использоваться для запуска служб, остановки служб или выполнения любых других команд, которые изменяют текущую работающую систему.
====

[[pkg-names]]
== Изменение имён файлов [.filename]#pkg-*#

Все имена файлов [.filename]#pkg-\*# определяются с помощью переменных, так что вы можете изменить их, если это нужно, в вашем файле [.filename]#Makefile#. Это особенно полезно, если вы используете одни и те же файлы [.filename]#pkg-*# совместно между несколькими портами или пишете в один из вышеперечисленных файлов (в главе о crossref:porting-dads[porting-wrkdir,"записи в каталоги, отличные от ``WRKDIR``"] объяснено, почему не рекомендуется осуществлять запись непосредственно в файлы [.filename]#pkg-*#).

Вот список имён переменных и их значений по умолчанию. (Значение `PKGDIR` по умолчанию равно `${MASTERDIR}`.)

[.informaltable]
[cols="1,1", frame="none", options="header"]
|===
| Переменная
| Значение по умолчанию

|`DESCR`
|`${PKGDIR}/pkg-descr`

|`PLIST`
|`${PKGDIR}/pkg-plist`

|`PKGINSTALL`
|`${PKGDIR}/pkg-install`

|`PKGPREINSTALL`
|`${PKGDIR}/pkg-pre-install`

|`PKGPOSTINSTALL`
|`${PKGDIR}/pkg-post-install`

|`PKGDEINSTALL`
|`${PKGDIR}/pkg-deinstall`

|`PKGPREDEINSTALL`
|`${PKGDIR}/pkg-pre-deinstall`

|`PKGPOSTDEINSTALL`
|`${PKGDIR}/pkg-post-deinstall`

|`PKGMESSAGE`
|`${PKGDIR}/pkg-message`
|===

[[using-sub-files]]
== Использование `SUB_FILES` и `SUB_LIST`

Переменные `SUB_FILES` и `SUB_LIST` подходят для задания в файлах порта динамических значений, таких как `PREFIX` установки в [.filename]#pkg-message#.

В переменной `SUB_FILES` указывается перечень файлов для автоматического изменения. Каждый _file_ из перечня `SUB_FILES` обязан иметь соответствующий [.filename]#file.in#, присутствующий в `FILESDIR`. Измененная версия будет создана в `WRKDIR`. Файлы, определённые в качестве значения `USE_RC_SUBR` (или устаревшего `USE_RCORDER`), автоматически добавляются в `SUB_FILES`. Для файлов [.filename]#pkg-message#, [.filename]#pkg-install# и [.filename]#pkg-deinstall# устанавливается соответствующая переменная Makefile, указывающая на обработанную версию.

Переменная `SUB_LIST` содержит перечень пар `VAR=VALUE`. В каждом файле из `SUB_FILES` для каждой пары будет произведена замена `%%VAR%%` на `VALUE`. Некоторые общие пары определяются автоматически: `PREFIX`, `LOCALBASE`, `DATADIR`, `DOCSDIR`, `EXAMPLESDIR`, `WWWDIR` и `ETCDIR`. Любая строка, начинающаяся с `@comment`, будет удалена из конечного файла после подстановки переменной.

В следующем примере в [.filename]#pkg-message# будет сделана замена `%%ARCH%%` на системную архитектуру:

[.programlisting]
....
SUB_FILES=	pkg-message
SUB_LIST=	ARCH=${ARCH}
....

Обратите внимание, что в этом примере в `FILESDIR` обязательно существование файла [.filename]#pkg-message.in#.

Пример хорошего [.filename]#pkg-message.in#:

[.programlisting]
....
Now it is time to configure this package.
Copy %%PREFIX%%/shared/examples/putsy/%%ARCH%%.conf into your home directory
as .putsy.conf and edit it.
....
