Python module os.chmod(file, 664) does not change the permission to rw-rw-r— but -w--wx----

前端 未结 6 951
轮回少年
轮回少年 2020-12-13 01:42

Recently I am using Python module os, when I tried to change the permission of a file, I did not get the expected result. For example, I intended to change the permission to

相关标签:
6条回答
  • 2020-12-13 02:27

    Use permission symbols instead of numbers

    Your problem would have been avoided if you had used the more semantically named permission symbols rather than raw magic numbers, e.g. for 664:

    #!/usr/bin/env python3
    
    import os
    import stat
    
    os.chmod(
        'myfile',
        stat.S_IRUSR |
        stat.S_IWUSR |
        stat.S_IRGRP |
        stat.S_IWGRP |
        stat.S_IROTH
    )
    

    This is documented at https://docs.python.org/3/library/os.html#os.chmod and the names are the same as the POSIX C API values documented at man 2 stat.

    Another advantage is the greater portability as mentioned in the docs:

    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.

    chmod +x is demonstrated at: How do you do a simple "chmod +x" from within python?

    Tested in Ubuntu 16.04, Python 3.5.2.

    0 讨论(0)
  • 2020-12-13 02:30

    Found this on a different forum

    If you're wondering why that leading zero is important, it's because permissions are set as an octal integer, and Python automagically treats any integer with a leading zero as octal. So os.chmod("file", 484) (in decimal) would give the same result.

    What you are doing is passing 664 which in octal is 1230

    In your case you would need

    os.chmod("/tmp/test_file", 436)
    

    [Update] Note, for Python 3 you have prefix with 0o (zero oh). E.G, 0o666

    0 讨论(0)
  • 2020-12-13 02:32

    So for people who want semantics similar to:

    $ chmod 755 somefile
    

    Use:

    $ python -c "import os; os.chmod('somefile', 0o755)"
    

    If your Python is older than 2.6:

    $ python -c "import os; os.chmod('somefile', 0755)"
    
    0 讨论(0)
  • 2020-12-13 02:32

    If you have desired permissions saved to string then do

    s = '660'
    os.chmod(file_path, int(s, base=8))
    
    0 讨论(0)
  • 2020-12-13 02:33

    leading 0 means this is octal constant, not the decimal one. and you need an octal to change file mode.

    permissions are a bit mask, for example, rwxrwx--- is 111111000 in binary, and it's very easy to group bits by 3 to convert to the octal, than calculate the decimal representation.

    0644 (octal) is 0.110.100.100 in binary (i've added dots for readability), or, as you may calculate, 420 in decimal.

    0 讨论(0)
  • 2020-12-13 02:33

    Using the stat.* bit masks does seem to me the most portable and explicit way of doing this. But on the other hand, I often forget how best to handle that. So, here's an example of masking out the 'group' and 'other' permissions and leaving 'owner' permissions untouched. Using bitmasks and subtraction is a useful pattern.

    import os
    import stat
    def chmodme(pn):
        """Removes 'group' and 'other' perms. Doesn't touch 'owner' perms."""
        mode = os.stat(pn).st_mode
        mode -= (mode & (stat.S_IRWXG | stat.S_IRWXO))
        os.chmod(pn, mode)
    
    0 讨论(0)
提交回复
热议问题