在setup.py文件中设置文件权限

时间:2011-05-09 05:16:14

标签: python setup.py

我使用setup.py创建了一个python软件安装。在这个软件中,当我使用setup.py安装这些xml文件时,我使用数据文件(XML文件),然后这些文件与/usr/lib/python2.7/site_packages/XYZ中的其他文件一起保存。但是设置为这些文件的文件权限(XML文件)rwx------意味着只有超级用户(root)可以读取这些文件我想要更改XML文件的文件权限,因为rwxr-----表示当前用户也可以读取该文件文件。如何更改数据文件权限。

4 个答案:

答案 0 :(得分:10)

执行此操作的正确方法是覆盖install命令,以下是如何执行此操作。

首先在setup.py开头添加以下导入:

from setuptools.command.install import install
from distutils import log # needed for outputting information messages 

然后你需要创建一个可调用的命令类,这里是一个例子,我创建一个安装脚本的命令类,并确保它只是root的可执行文件(这是python中的其他方法)。例如,如果您的UID不是0,您可以随时退出脚本。) 我也在这里使用另一个导入:

from setuptools.command.install_scripts import install_scripts

class OverrideInstall(install):

    def run(self):
        uid, gid = 0, 0
        mode = 0700
        install.run(self) # calling install.run(self) insures that everything that happened previously still happens, so the installation does not break! 
        # here we start with doing our overriding and private magic ..
        for filepath in self.get_outputs():
            if self.install_scripts in filepath:
                log.info("Overriding setuptools mode of scripts ...")
                log.info("Changing ownership of %s to uid:%s gid %s" %
                         (filepath, uid, gid))
                os.chown(filepath, uid, gid)
                log.info("Changing permissions of %s to %s" %
                         (filepath, oct(mode)))
                os.chmod(filepath, mode)

现在已经创建了类。我通知安装程序,在命令行中看到install时,应该调用此类:

setup(
      # keep
      # all the previous keywords you had ...
      # add
      cmdclass={'install': OverrideInstall}
      ) 

我希望这个答案有所帮助。

答案 1 :(得分:1)

我使用setup.py来构建各种RPM。解决方案对我来说有点不同。我还认为它更强大有两个原因:

  1. 我可以显式覆盖文件的权限
  2. 我不需要知道用户的uid和gid。相反,我可以使用纯文本。
  3. 这是一个工作示例

    from distutils.core import setup
    import distutils.command.bdist_rpm
    import distutils.command.install
    
    version='13'
    
    data_files = [
        ('/usr/share/blah', ['README', 'test.sh']),
    ]
    
    permissions = [
        ('/usr/share/blah', 'test.sh', '(755, sri, sri)'),
    ]
    
    class bdist_rpm(distutils.command.bdist_rpm.bdist_rpm):
    
        def _make_spec_file(self):
            spec = distutils.command.bdist_rpm.bdist_rpm._make_spec_file(self)
            for path, files , perm in permissions:
    
                ##
                # Add a line to the SPEC file to change the permissions of a
                # specific file upon install.
                #
                # example:
                #   %attr(666, root, root) path/file
                #
                spec.extend(['%attr{} {}/{}'.format(perm, path, files)])
    
            return spec
    
    
    setup(name='sri-testme',
          version=version,
          description='This is garganbe and is only used to test the permision flag behavior',
          author='Chris Gembarowski',
          author_email='chrisg@summationresearch.com',
          url='https://www.python.org/sigs/distutils-sig/',
          data_files=data_files,
          cmdclass={'bdist_rpm':bdist_rpm}
         )
    

    让我更详细地解释一下发生了什么。 RPM是从SPEC文件构建的。 bdist_rpm构建一个SPEC文件。在SPEC文件中,您可以通过提供%attr选项来选择文件的权限和所有权。

    在示例中,使test.sh可执行并由用户拥有,并且由sri'我会将%attr(755, sri, sri)添加到SPEC文件的末尾。

    因此,当我覆盖bdist_rpm._make_spec_file的行为时,我所做的就是为每个要覆盖权限的文件添加一行。

    此示例中的完整SPEC文件为:

    %define name sri-testme
    %define version 13
    %define unmangled_version 13
    %define release 1
    
    Summary: This is garganbe and is only used to test the permision flag behavior
    Name: %{name}
    Version: %{version}
    Release: %{release}
    Source0: %{name}-%{unmangled_version}.tar.gz
    License: UNKNOWN
    Group: Development/Libraries
    BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
    Prefix: %{_prefix}
    BuildArch: noarch
    Vendor: Chris Gembarowski <chrisg@summationresearch.com>
    Url: https://www.python.org/sigs/distutils-sig/
    
    %description
    UNKNOWN
    
    %prep
    %setup -n %{name}-%{unmangled_version}
    
    %build
    python setup.py build
    
    %install
    python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
    
    %clean
    rm -rf $RPM_BUILD_ROOT
    
    %post
    ##
    # sri will be turned on in the run-once script instead of here
    #
    
    
    %preun
    #!/bin/bash
    
    
    
    %files -f INSTALLED_FILES
    %defattr(-,root,root)
    %attr(755, sri, sri) /usr/share/blah/test.sh
    

答案 2 :(得分:0)

无需编辑setup.py

的解决方案

如果您只想安装现有软件包而不编辑其setup.py,请尝试

sudo sh -c 'umask 0; \
    python setup.py install --installed files.txt && \
    xargs chmod -R a+rX < files.txt'

通过编辑setup.py

的解决方案

如果可以选择编辑setup.py文件,则可以通过快速修复将其添加到setup.py的顶部:

import os, subprocess
# Set a reasonable umask.
os.umask(0o022)
# Make all local files readable and all directories listable.
subprocess.call(['chmod', '-R', 'a+rX', '.'])

这将在Linux上运行,但可能无法在其他OS上运行。如果您需要支持其他操作系统,或者只想更改已安装文件的权限,请使用this other answer中更复杂的名称替换chmod调用。

说明

除了复制文件时,setup.py install在创建只能由root读取的文件夹时遇到了问题,因此htey仅可由root读取。事实证明,setup.py创建的文件夹的权限是由我的umask确定的,我相信setup.py复制的文件的权限会保留,但是我对此不太确定。

规范性声明:)

我认为使用合理的默认值应该是setup.py install的责任-例如,当我使用apt安装软件时,它会忽略我的umask

答案 3 :(得分:-6)

以root用户身份登录,并在shell中输入:

  

chmod 744 yourfilename