11

That is my setup:

I have a VirtualMachine (Ubuntu 14.04. LTS), where there is running a PostgreSQL/PostGIS database.

With Windows 7 in QGIS I connect to this database and load feature layer into my GIS project.

With some python code I create a file with a tile ID and some information.

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(' ', ''))

The file has the permissions:

-rwx------

I want to set also the same permissions for my group and other.

-rwxrwxrwx

I tried:

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

No success.

What was working is:

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

OR

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

Why doesn't work the chmod command?

Under UNIX I can chmod this file and I'am the same user like in Windows.

I also tried the os.chmod method. But no success.

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

When I do a "chmod 777 file" under UNIX (Solaris) the permissions are

-rwxrwxrwx

What I can do now is to downgrade/remove permissions under Windows in the GIS project:

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

With this command I get a 0 feedback in the python console output

I also get a 0 feedback when I do a chmod 777 on the new file but nothing happens.

The Problem is that I can only downgrade permissions. I can't set new permissions!

Stefan
  • 1,383
  • 2
  • 15
  • 25
  • Can you print the return of each `subprocess.call (...)` ? It will help locate the bug. – Diane M Jan 06 '16 at 11:10
  • Are you running the script on the Windows or the Linux machine? If the H: drive is a Samba shared folder, running my Windows answer on the Windows machine may work. If it doesn't, you may need to set permissions in the `/etc/samba/smb.conf` file in the Linux server. – Ronan Paixão Jan 06 '16 at 11:46
  • I'm running the script in Windows. – Stefan Jan 13 '16 at 20:18

3 Answers3

5

From the os module documentation:

Note: Although Windows supports chmod(), you can only set the file’s read-only flag with it (via the stat.S_IWRITE and stat.S_IREAD constants or a corresponding integer value). All other bits are ignored.

For Windows permissions, you manage the ACLs. Adapting from another answer, you need the pywin32 library:

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)

Change the con.FILE_ALL_ACCESS flag to the ones you need.

Community
  • 1
  • 1
Ronan Paixão
  • 8,297
  • 1
  • 31
  • 27
3

What is the intention with the r character in your shell commands? Do you mean to put it in front of the entire string? Have you checked which file is generated by touch?

When I try your example, it runs this command: ['touch', 'rH:\\path_to_file\x0cile.txt'], that is creating the file rH:\path_to_file\file.txt

This works fine for me:

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

relet
  • 6,819
  • 2
  • 33
  • 41
2

Try this (I don't have a Linux machine right now to test it):

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

If the filename is user-supplied, you should avoid shell=True for security reasons. You may try:

filename = r"H:\path_to_file\file.txt"
subprocess.call(['chmod','777',filename])
Ronan Paixão
  • 8,297
  • 1
  • 31
  • 27