11

How can we remove a particular permission for all using os.chmod ?

In short, how can we write the below using os.chmod

chmod a-x filename

I do know that we can add permission to an existing one and remove also.

In [1]: import os, stat
In [5]: os.chmod(file, os.stat(file).st_mode | stat.S_IRGRP)  # Make file group readable.

But I am not able to figure out the doing the all operation

baky
  • 631
  • 1
  • 8
  • 17
  • Think about how `chmod` might achieve that; what steps would it need to take to remove a permission from the existing octal permissions value? – Martijn Pieters Sep 23 '14 at 06:45
  • Instead of complementing/inverting, I was xoring the values. Appreciate the reasoning. Thanks . – baky Sep 23 '14 at 06:55

2 Answers2

20

Cool. So the secret is you first need to get the current permissions. This is a bit of a mess, but it works.

current = stat.S_IMODE(os.lstat("x").st_mode)

The idea is that lstat.st_mode gives you the flags, but you need to crop that to the range that chmod accepts:

help(stat.S_IMODE)
#>>> Help on built-in function S_IMODE in module _stat:
#>>>
#>>> S_IMODE(...)
#>>>     Return the portion of the file's mode that can be set by os.chmod().
#>>>

Then you can remove the stat.S_IEXEC flag with some bit operations, and this gives you the new number to use:

os.chmod("x", current & ~stat.S_IEXEC)

If you're not familiar with bit twiddling, & takes only those bits that both numbers have, and ~ inverts the bits of a number. so x & ~y takes those bits that x has and that y doesn't have.

Veedrac
  • 58,273
  • 15
  • 112
  • 169
-1

If you want to use os.chmod() then you can use below code:

import os
for dir_path, dir_names, files in os.walk('.'):
        for file in files:
            abs_path = os.path.join(dirpath, file)
            os.chmod(abs_path, 0o755) 
Nikhil Gupta
  • 271
  • 2
  • 4
  • This is absolutely not what the question meant. 'chmod a-x filename' means revoking the executable permissions from all the users(user owner, group owner and others) for the given filename. – baky Sep 23 '14 at 09:17
  • So What permissions you want to provide to user owner, group owner and others. All should not have execute permission, that I got. What about read and write permission? Then I will make the changes. – Nikhil Gupta Sep 23 '14 at 09:21
  • import os for dir_path, dir_names, files in os.walk('.'): for file in files: abs_path = os.path.join(dirpath, file) os.chmod(abs_path, 0o644) # It will provide Read and write to owner, only read to other users – Nikhil Gupta Sep 23 '14 at 10:50
  • Just for the sake of your curosity: "What about read and write permission? " The qn meant removing exetuble permission for the file from all the users. This ideally means that we should retain the other previous permissions the file had. And again, why are you doing os.walk('.') ? The qn mentions just one file, not the entire directory. – baky Sep 23 '14 at 14:12