I can use os.stat(pathname) to get pathname's perssmions, mtime, atime....
Howerver, I hava a file that has a '+i' attribute, you can see it by:
lsattr /tmp/test.py
Is there a way to know if the pathname has the '+i' attribute by using python?
There doesn't appear to be an os module function to get these Linux file attributes, but you can use the subprocess module to call the lsattr command in Python.
The code below should work on Python 2 or 3, although it can be made more compact in recent Python versions.
FWIW, I have the i bit set on my fstab file because I got sick of it randomly getting wiped out.
import subprocess
def is_immutable(fname):
p = subprocess.Popen(['lsattr', fname], bufsize=1, stdout=subprocess.PIPE)
data, _ = p.communicate()
#print(data)
return 'i' in data.split(None, 1)[0]
print(is_immutable("/etc/fstab"))
The previous version of this code had
return 'i' in data.split
However, that will also detect an 'i' if one is present in the file name! The new version only detects an 'i' in the attribute flags. Thanks, sverasch for bring this to my attention.
This related SO post about why os.chflags doesn't exist on Linux shows a way to work around the absence of lsattr in the os module using fcntl. However, it relies on copying constant definitions from a header file (ext2fs/ext2_fs.h), so it's fragile. A more permanent solution would require writing some C or something like Cython.
Meanwhile, PM 2Ring's answer works, though it should be modified to work with paths that contain the letter "i". Perhaps someone with some reputation could comment or edit that answer (this is my first post)?
import subprocess
def is_immutable(fname):
p = subprocess.Popen(['lsattr', fname], bufsize=1, stdout=subprocess.PIPE)
data, _ = p.communicate()
#print(data)
return 'i' in data
def is_immutable_safe(file_path):
"""Check if the immutable flag is set on a Linux file path
Uses the lsattr command, and assumes that the immutable flag
appears in the first 16 characters of its output.
"""
return 'i' in subprocess.check_output(['lsattr', file_path])[:16]
# These assertions will pass if the immutable bit is not set on
# /etc/inittab on your system
assert is_immutable('/etc/inittab') is True
assert is_immutable_safe('/etc/inittab') is False