3

What's the equivalent of this bash command in Python?

chmod -R u+x $dir_path

There is os.fchmod but not sure if it applies recursively as the original command does.

Does this do the same thing that I want?

import os
import stat
from pathlib import Path

fd = Path(dir_path).open().fileno()
os.fchmod(fd, stat.S_IXUSR)
Rudy Matela
  • 6,310
  • 2
  • 32
  • 37
adhnguyen
  • 33
  • 3
  • Perhaps `os.walk(path)` and then `os.chmod()` each file individually. No need to use the `os.fchmod(fd)` variant which requires a file handle. Of course, you could always use `os.system()` to run chmod. – jarmod Nov 18 '21 at 14:36
  • 1
    duplicate (?) of https://stackoverflow.com/questions/2853723/what-is-the-python-way-for-recursively-setting-file-permissions – Demi-Lune Nov 18 '21 at 14:38
  • @Demi-Lune almost the same, though that question relates to file ownership. – jarmod Nov 18 '21 at 14:38

1 Answers1

2

You can use os.chmod but that'll only change permissions of that individual file or directory. To change permissions of a single file incrementally (by adding to the existing permissions), use:

import os
import stat

st = os.stat("path/to/file")
os.chmod("/path/to/file", st.st_mode | stat.S_IXUSR)

Now, to change permissions of files in a directory recursively, you would need to use os.walk to traverse through all sub directories and their files:

import os
import stat

for root, dirs, files in os.walk("path/to/directory"):
    for name in dirs:
        path = os.path.join(root, name)
        st = os.stat(path)
        os.chmod(path, st.st_mode | stat.S_IXUSR)
    for name in files:
        path = os.path.join(root, name)
        st = os.stat(path)
        os.chmod(path, st.st_mode | stat.S_IXUSR)

The above will both traverse subdirectories and will incrementally modify permissions only to add user execution permissions.

There are other alternatives, one fun and obvious one is:

os.system("chmod -R u+x /path/to/file")

For future reference, here are two related questions:

Rudy Matela
  • 6,310
  • 2
  • 32
  • 37