问题 使用python设置组权限


这是我的设置:

我有一个VirtualMachine(Ubuntu 14.04.LTS),其中运行PostgreSQL / PostGIS数据库。

使用QGIS中的Windows 7,我连接到此数据库并将要素图层加载到我的GIS项目中。

使用一些python代码,我创建一个带有tile ID和一些信息的文件。

import os
import io
import time

layer=None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
if lyr.name() == "fishnet_final":
    layer = lyr

for f in layer.selectedFeatures():
    pth = os.path.join(os.path.dirname(r'H:\path_to_file\'), str(f['name']) + "_" + str(time.strftime("%Y-%m-%d")) + "_" + str(f['country']) + ".txt")
    fle = open(pth,'wb')    
    fle.writelines(str(f['name']))
    fle.write('\n')
    fle.write(str(time.strftime("%Y-%d-%m")))
    fle.write('\n')
    fle.write(str(f['country']))
    fle.write('\n')
    fle.close()
    os.rename(pth, pth.replace(' ', ''))

该文件具有以下权限:

-rwx------

我想为我的组和其他人设置相同的权限。

-rwxrwxrwx

我试过了:

import shlex
command=shlex.split("chmod 777 r'H:\path_to_file\file.txt'") 
subprocess.call(command)

没有成功。

工作的是:

command=shlex.split("touch r'H:\path_to_file\file.txt'")

要么

command=shlex.split("rm r'H:\path_to_file\file.txt'")

为什么不能使用chmod命令?

在UNIX下我可以chmod这个文件,我和Windows中的用户一样。

我也尝试过os.chmod方法。但没有成功。

import os, stat
st = os.stat(r'H:\path_to_file\file.txt')
os.chmod(r'H:\path_to_file\file.txt', st.st_mode | 0o111 )

UPDATE

当我在UNIX(Solaris)下执行“chmod 777文件”时,权限是

-rwxrwxrwx

我现在可以做的是在GIS项目中降级/删除Windows下的权限:

subprocess.call(r'chmod 400 "H:\path_to_file\file.txt"', shell=True)
0
-r-xr-xr-x

有了这个命令,我得到了一个 0 python控制台输出中的反馈

我也得到了 0 当我在新文件上执行chmod 777时反馈,但没有任何反应。

问题是我只能降级权限。我无法设置新权限!


2387
2017-12-17 15:28


起源

你能打印出每个的回报吗? subprocess.call (...) ?它将有助于找到错误。 - Arthur Havlicek
您是在Windows或Linux计算机上运行脚本吗?如果H:驱动器是Samba共享文件夹,则在Windows计算机上运行Windows答案可能会起作用。如果没有,您可能需要在中设置权限 /etc/samba/smb.conf Linux服务器中的文件。 - Ronan Paixão
我在Windows中运行脚本。 - Stefan


答案:


来自 os模块文档

注意:尽管Windows支持chmod(),但您只能使用它设置文件的只读标志(通过stat.S_IWRITE和stat.S_IREAD常量或相应的整数值)。 所有其他位都被忽略。

对于Windows权限,您可以管理ACL。适应 另一个答案,你需要的 pywin32 图书馆:

import win32security
import ntsecuritycon as con

FILENAME = r"H:\path_to_file\file.txt"

user, domain, type = win32security.LookupAccountName ("", "Your Username")

sd = win32security.GetFileSecurity(FILENAME, win32security.DACL_SECURITY_INFORMATION)
dacl = sd.GetSecurityDescriptorDacl()   # instead of dacl = win32security.ACL()

dacl.AddAccessAllowedAce(win32security.ACL_REVISION, con.FILE_ALL_ACCESS, user)

sd.SetSecurityDescriptorDacl(1, dacl, 0)   # may not be necessary
win32security.SetFileSecurity(FILENAME, win32security.DACL_SECURITY_INFORMATION, sd)

改变 con.FILE_ALL_ACCESS 标记你需要的那些。


5
2018-01-06 11:40



感谢您的回答。我对这个答案中的步骤仍然没有成功。明天会给它最后一次尝试。 - Stefan
您是否将“您的用户名”字符串更改为您的实际用户名? - Ronan Paixão


shell命令中r字符的意图是什么?你的意思是把它放在整个弦的前面吗? 您是否检查过通过触摸生成了哪个文件?

当我尝试你的例子时,它运行这个命令: ['touch', 'rH:\\path_to_file\x0cile.txt'],即创建文件 rH:\path_to_file\file.txt

这对我来说很好:

command=shlex.split("chmod 777 'H:\path_to_file\file.txt'") subprocess.call(command)


3
2018-01-06 10:53



我再次尝试使用你的建议,但它不起作用。我已经更新了我的答案。 - Stefan


试试这个(我现在没有Linux机器来测试它):

import subprocess
subprocess.call(r'chmod 777 "H:\path_to_file\file.txt"', shell=True)

如果文件名是用户提供的,则应避免使用 shell=True 出于安全原因。你可以尝试:

filename = r"H:\path_to_file\file.txt"
subprocess.call(['chmod','777',filename])

2
2018-01-06 11:16