Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
371 views
in Technique[技术] by (71.8m points)

python 2.7 - Why doesn't os.chflags() work under Linux?

I'm using Python 2.7.9 under Debian GNU/Linux 8 (jessie) 64-bit. I just tried to change file attributes by calling os.chflags(path, mode). In the Python docs there is an article about the os interface which says that this method is available in Unix, but it doesn't work for Linux. Python always throws:

Traceback (most recent call last):
File "/home/lexer/py/epam/tests/main.py", line 43, in <module>
os.chflags(path_to_file(file_name), stat.SF_NOUNLINK)
AttributeError: 'module' object has no attribute 'chflags'

There is an issue which was already raised for that a long time ago, but I still can't understand why os.chflags() doesn't do the chattr command's job. Could anybody elaborate it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Linux does not provide the chflags syscall, so Python does not provide the wrapper os.chflags().

The chattr command uses the code (e2fsprogs-1.42.13's lib/e2p/fsetflags.c):

        fd = open (name, OPEN_FLAGS);
        if (fd == -1)
                return -1;
        f = (int) flags;
        r = ioctl (fd, EXT2_IOC_SETFLAGS, &f);
        if (r == -1)
                save_errno = errno;
        close (fd);

to set the extended attributes for a file, so if you port that to Python (and use some C to extract the value for EXT2_IOC_SETFLAGS from ext2fs/ext2_fs.h), you can do something like:

#!/usr/bin/python2

import fcntl
import os
import struct

# Taken from ext2fs/ext2_fs.h.
EXT2_IMMUTABLE_FL = 0x00000010
EXT2_IOC_SETFLAGS = 0x40086602

fd = os.open('/var/tmp/testfile', os.O_RDWR)
f = struct.pack('i', EXT2_IMMUTABLE_FL)
fcntl.ioctl(fd, EXT2_IOC_SETFLAGS, f);
os.close(fd)

Et voilà:

[tim@passepartout ~]$ lsattr /var/tmp/testfile
----i----------- /var/tmp/testfile
[tim@passepartout ~]$

But for all practical purposes it is probably much more prudent to execute chattr(1) as a child process than to turn the proof-of-concept above into something that runs reliably without maintenance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...