如何使用deb软件包创建目录并更改其所有者

我需要创建一个deb包,用于创建日志目录。我想要创建目录/var/logs/my_package并将其所有者更改为my_user
文档中有信息,我可以创建文件debian/dir。但是有信息说这不是最好的方法。而且没有说明应该如何更改目录所有者(我正在考虑将命令chown my_user.my_user /var/logs/my_package放在debian/postinst文件中)。
创建deb包时,有什么推荐的方法来创建目录?
3个回答

你是对的,你需要一个 debian/my_package.postinst 文件来执行这样的操作。
#!/bin/sh

#DEBHELPER#

set -e

DIR="/var/log/my_package/"
USER="my_user"

mkdir -p ${DIR}    
if id -u ${USER} > /dev/null 2>&1; then    
    chown ${USER}:${USER} ${DIR}
fi

注意:脚本在调用chown之前会检查用户是否存在。

2非常抱歉,但是这并没有回答我的问题。 - bessarabov
请解释一下为什么这个 postinst 脚本没有回答你最初的问题。现在我有点困惑了。 - Sylvain Pineau
1非常抱歉我没有以正确的方式解释。您的解决方案很好,这就是我已经实施的。但是文档中说“这通常意味着Makefile存在问题。”我理解这个消息是指还有其他方法来完成此任务。我想找出推荐的方法是什么。 - bessarabov
1目录的创建可以在debian/rules中完成,这是Debian软件包的Makefile。由于我不知道你的debian/rules,所以我更倾向于提出一个基于单个文件的解决方案。但是chown命令必须作为安装后的处理过程。应该避免使用debian/dirs,但我的初始答案完全没问题。请投票并接受它,谢谢。 - Sylvain Pineau
有一个拼写错误。结尾应该是 postinst 而不是 postint - kayn

你不需要创建一个postinst脚本,但解决方案还是有点棘手。我在debian/rules中使用了dh通配符。
#!/usr/bin/make -f
%:
        dh $@

binary:
        dh $@

这个程序可以完成所有需要的工作。但是我需要覆盖一些目录的所有权(我们称之为数据)。因此,我必须做出一些例外,我使用以下特殊指令:

    override_dh_install:
        dh_install   #calls default *.install and *.dirs installation
        install -d -o www-data -g www-data $(CURDIR)/debian/<package_name>/var/www/<something>/data 

数据目录不需要在*.dirs文件中。但是还有一个技巧。Debhelper包含脚本dh_fixperms,它会将所有权修复回root,所以我们也需要进行覆盖:
override_dh_fixperms:
    dh_fixperms --exclude data

这就是全部。记住,数据目录不算作一个conffile,所以在卸载软件包时会被删除。如果你需要将其设置为conffile,那就是另外一回事了。


1这是否要求用户和组在构建软件包的系统上存在?如果是的话,是否有一种基于Debian的机制可以确保这一点? - moritz
1这将在用于构建Debian软件包的系统上创建目录,而不是安装该软件包的系统。 - gerardw
@moritz 是的。这就是这种技术的缺点。它需要在两个系统上都存在。 - Alexis Wilke
我认为在*.dirs文件中使用install -d ...并不合理,因为两者都会创建目录。在我的情况下,我只需在rules文件中使用chown ... - Alexis Wilke

我读到过,如果你必须使用debian/[.]dirs文件,那意味着你的make install步骤没有正确完成其工作。该步骤应该创建该文件夹。
以下是我发现的问题:
1. make install无法在除了/usr(对于Debian软件包)之外的目录下安装任何内容,所以如果你想要一个位于/etc/.../var/lib//...等目录下的文件夹,它就没用了。
2. 如果你在debian/[.]postinst脚本中使用了mkdir -p ...,那么你需要在debian/[.].postrm脚本中手动使用rmdir ...来删除它。
所以Marek Šimon提出的解决方案与我的相同,唯一的区别是我使用chown ...而不是install -d ...,尽管使用install -d ...可以完全避免debian/[<package>.]dirs。个人而言,我喜欢在一个单独的文件中看到我创建的目录列表,这样看起来更清晰明了。

示例

创建这些目录:

# in debian/package.dirs
/etc/package/magic/configuration
/var/www/package/data

更改所有权:

# in debian/rules
override_dh_fixperms:
    dh_fixperms
    chmod 700 debian/tmp/var/www/package/data
    chown www-data:www-data debian/tmp/var/www/package/data

警告: debian/rules 文件使用制表符缩进目标名称下的代码。 这非常重要。
如示例所示,我也经常更改权限(chmod)。
如果您创建两个或多个软件包,则需要使用debian/tmp/...引导程序。 如果您只创建一个软件包,则我不太确定它是什么(部分原因是我的项目很少只有一个软件包,而且当您添加第二个软件包时,许多路径会发生变化,因此我总是至少包括一个几乎为空的package-doc.install,以便它不会对我产生影响)。
最后注意:
如果您要创建要由Debian或Ubuntu接受的公共Debian软件包,则可能要遵循Sylvain Pineau的解决方案。 请记住,在清除操作中,您需要删除自己的目录(除非用户在其中创建了自己的文件)。