Mô-đun Python os.chmod (tệp, 664) không thay đổi quyền đối với rw-rw-r— but -w - wx ----


111

Gần đây tôi đang sử dụng hệ điều hành mô-đun Python, khi tôi cố gắng thay đổi quyền của tệp, tôi không nhận được kết quả như mong đợi. Ví dụ: tôi định thay đổi quyền thành rw-rw-r--,

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

Quyền sở hữu thực sự là -w - wx --- (230)

--w--wx--- 1 ag ag 0 Mar 25 05:45 test_file

Tuy nhiên, nếu tôi thay đổi 664 thành 0664 trong mã, kết quả là những gì tôi cần, ví dụ:

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

Kết quả là:

-rw-rw-r-- 1 ag ag 0 Mar 25 05:55 test_file

Ai đó có thể giúp giải thích tại sao số 0 đứng đầu đó lại rất quan trọng để có được kết quả chính xác không?


33
Hệ bát phân. Hệ bát phân. Hệ bát phân.
Cole Johnson

6
Tôi đã gặp sự cố đối với tài liệu python tại bug.python.org/issue25377 vì điều đó phải rõ ràng trong tài liệu.
Karl Richter

Câu trả lời:


130

Tìm thấy điều này trên một diễn đàn khác

Nếu bạn đang thắc mắc tại sao số 0 đứng đầu lại quan trọng, đó là vì quyền được đặt dưới dạng số nguyên bát phân và Python tự động xử lý bất kỳ số nguyên nào có số 0 đứng đầu là số bát phân. Vì vậy, os.chmod ("tệp", 484) (ở dạng thập phân) sẽ cho kết quả tương tự.

Những gì bạn đang làm là chuyển 664cái mà trong hệ bát phân là1230

Trong trường hợp của bạn, bạn sẽ cần

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

[Cập nhật] Lưu ý, đối với Python 3, bạn có tiền tố 0o (zero oh). VÍ DỤ,0o666


1
Cảm ơn, nhưng tôi vẫn nhầm lẫn rằng, 484 trong hệ thập phân có nghĩa là 744 trong bát phân, điều này có ý nghĩa trong chủ đề bạn đã đề cập trong diễn đàn. Tuy nhiên, nếu tôi cho 644 ở dạng thập phân, nó sẽ chuyển thành 1204 ở dạng bát phân. Làm thế nào để 1204 liên quan đến 230 trong bát phân?
AplusG

2
@AplusG: các 1không bỏ đi! Đó là bit dính / setuid / setgid, và 1 nghĩa là sticky. Sử dụng ls -lbạn có thể nhận thấy quyền hiện nay bao gồm một Tcuối cùng ...
MestreLion

2
dễ dàng hơn để thêm 0 và làm cho nó bát phân :)
radtek

10
Lưu ý, đối với Python 3, bạn có tiền tố 0o (zero oh).
Mawg nói hãy phục hồi Monica

1
Tôi sử dụng 0o trong python 2.7.10
Wyrmwood

125

Vì vậy, đối với những người muốn ngữ nghĩa tương tự như:

$ chmod 755 somefile

Sử dụng:

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

Nếu Python của bạn cũ hơn 2.6:

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

12
Định dạng python3 cũng hoạt động trong python 2.7.9. Tôi đã không kiểm tra các phiên bản trước đó.
Fred Mitchell

3
Cú pháp Python 3 hoạt động trở lại Python 2.6 docs.python.org/3/whatsnew/…
Pete

Làm việc cho mình tks!
LandiLeite

Có lẽ nên là 00755, chỉ để làm rõ ràng các bit suid / sgid / stick đi đâu, trong trường hợp một số nhà phát triển sau này đến và muốn sử dụng tập lệnh cũ này, chẳng hạn như sgid với 2755nhưng sau đó không thể tìm ra lý do các khung được vặn hoàn toàn. ;)
dannysauer

10

hàng đầu 0có nghĩa là đây là hằng số bát phân , không phải hằng số thập phân. và bạn cần một số bát phân để thay đổi chế độ tệp.

quyền là một chút mặt nạ, ví dụ, rwxrwx---111111000ở dạng nhị phân, và nó rất dễ dàng để bit nhóm 3 để chuyển sang bát phân, hơn tính toán các đại diện thập phân.

0644(bát phân) 0.110.100.100ở dạng nhị phân (tôi đã thêm dấu chấm để dễ đọc) hoặc như bạn có thể tính toán, 420ở dạng thập phân.


5

Sử dụng ký hiệu quyền thay vì số

Vấn đề của bạn sẽ được tránh nếu bạn sử dụng các ký hiệu quyền được đặt tên theo ngữ nghĩa hơn là các số ma thuật thô, ví dụ: cho 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
)

Điều này được ghi lại tại https://docs.python.org/3/library/os.html#os.chmod và tên giống với các giá trị API POSIX C được ghi lại tại man 2 stat.

Một ưu điểm khác là tính di động lớn hơn như đã đề cập trong tài liệu:

Lưu ý: Mặc dù Windows hỗ trợ chmod(), bạn chỉ có thể đặt cờ chỉ đọc của tệp với nó (thông qua hằng số stat.S_IWRITEstat.S_IREADhoặc một giá trị số nguyên tương ứng). Tất cả các bit khác đều bị bỏ qua.

chmod +xđược trình bày tại: Làm thế nào để bạn thực hiện một "chmod + x" đơn giản từ bên trong python?

Đã thử nghiệm trong Ubuntu 16.04, Python 3.5.2.


1
Đây là cách chính xác để giải quyết vấn đề.
carthurs

Tôi biết điều này theo cách của con trăn nhưng Nó khó có thể xấu hơn :)
Tomasz Swider

2

Nếu bạn đã lưu các quyền mong muốn vào chuỗi thì hãy làm

s = '660'
os.chmod(file_path, int(s, base=8))

0

Với tôi, sử dụng mặt nạ bit stat. * Dường như là cách dễ dàng và rõ ràng nhất để thực hiện việc này. Nhưng mặt khác, tôi thường quên cách tốt nhất để xử lý điều đó. Vì vậy, đây là một ví dụ về việc che giấu quyền "nhóm" và "khác" và để nguyên quyền "chủ sở hữu". Sử dụng mặt nạ bit và phép trừ là một mô hình hữu ích.

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.