如何使用distutils处理配置文件以遵循UNIX的FHS?

10 投票
2 回答
3047 浏览
提问于 2025-04-16 01:46

假设我们有一个叫做 foo 的程序。

如果我们使用绝对路径:

setup(...,
      data_files=[...,
              ('/etc', ['foo.cfg'])]
)

那么输入 foo$ python setup.py --prefix=/usr/local 后,我们会得到 /etc/foo.cfg。可是根据FHS的规定,我们应该得到的是 /usr/local/etc/foo.cfg

那如果我们使用相对路径呢?

setup(...,
      data_files=[...,
              ('etc', ['foo.cfg'])]
)

如果我们使用默认的安装路径,也就是安装到 /usr,那么我们会得到 /usr/etc/foo.cfg。这又是个糟糕的结果。

那么,怎么才能正确地做呢?

附注:为了不让问题变得更复杂,我们假设这个程序 foo 不能在非 Unix 环境下运行。

2 个回答

5

看起来没有简单的方法。问题在于配置文件是特殊的数据文件,需要特别对待。

所以,我们需要自己写一个类:

class myinstall(distutils.command.install.install):
    if self.prefix == '/usr':
        self.conf_prefix = '/etc'
    else:
        self.conf_prefix = self.prefix + '/etc'

    install.finalize_options(self)

    def install_conf(self):
        self.mkpath((self.root or '') + self.conf_prefix)
        for file in self.distribution.conf_files:
        dest = (self.root or '') + self.conf_prefix + '/' +
            os.path.basename(file)
        self.copy_file(file, dest)

    # blah blah blah

然后:

setup(# blah blah blah
  conf_files = ['foo.cfg']
  cmdclass = {'install': myinstall,
      # blah blah blah
  }
)
5

其实,继承 distutils.command.install.install 这个类并不是必须的。你可以直接把 data_files 传给 setup,这在 distutils 的文档中有说明,具体可以参考'安装额外文件'的部分。

比如:

setup(
    ...
    data_files = [
        (conf_path, ['foo.cfg'])
    ]
)

这里的 conf_path 是根据你的需求来计算的。也就是说,你可以通过测试 sys.prefix 来构造它,而不是使用 self.prefix,就像 @weakish 上面所做的那样。

撰写回答