我使用 setup.py 创建了一个 python 软件安装。在这个软件中,当我使用 setup.py 安装这些 xml 文件时,我使用数据文件(XML 文件),然后这些文件与其他文件一起保存在/usr/lib/python2.7/site_packages/XYZ
. 但是为这些文件(XML 文件)设置的文件权限rwx------
意味着只有超级用户(root)可以读取这些文件我想更改 XML 文件的文件权限,因为rwxr-----
当前用户也可以读取该文件。如何更改数据文件权限。
4 回答
正确的方法是覆盖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}
)
我希望这个答案有帮助。
无需编辑的解决方案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,但可能不适用于其他操作系统。如果您需要支持其他操作系统,或者只想更改已安装文件的权限,则将chmod
调用替换为更复杂的调用,例如this other answer。
解释
setup.py install
除了复制文件以使 htey 只能由 root 读取之外,我在创建只能由 root 读取的文件夹时遇到了问题。事实证明, by 创建的文件夹的权限setup.py
是由 my 确定的umask
,我相信对 by 复制的文件的权限setup.py
被保留,但我对此不太确定。
规范性声明:)
我认为应该有责任setup.py install
使用健全的默认值——例如,当我apt
用来安装软件时umask
,它应该忽略我的。
我setup.py
用来构建各种 RPM。解决方案对我来说有点不同。我还认为它更强大有两个原因:
- 我可以明确地覆盖文件的权限
- 我不需要知道用户的uid和gid。相反,我可以使用纯文本。
这是一个工作示例
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
以 root 身份登录,并在 shell 中键入:
chmod 744 你的文件名