Modul Python os.chmod (file, 664) tidak mengubah izin menjadi rw-rw-r— tetapi -w - wx ----


111

Baru-baru ini saya menggunakan modul os Python, ketika saya mencoba mengubah izin file, saya tidak mendapatkan hasil yang diharapkan. Misalnya, saya bermaksud mengubah izin menjadi rw-rw-r--,

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

Izin kepemilikan sebenarnya -w - wx --- (230)

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

Namun, jika saya mengubah kode 664 menjadi 0664, hasilnya hanya yang saya butuhkan, mis

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

Hasilnya adalah:

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

Adakah yang bisa membantu menjelaskan mengapa awalan 0 itu begitu penting untuk mendapatkan hasil yang benar?


33
Oktal. Oktal. Oktal.
Cole Johnson

6
Saya membuka masalah untuk dokumentasi python di bugs.python.org/issue25377 karena itu seharusnya jelas dari dokumen.
Karl Richter

Jawaban:


130

Temukan ini di forum lain

Jika Anda bertanya-tanya mengapa nol di depan itu penting, itu karena izin ditetapkan sebagai bilangan bulat oktal, dan Python secara otomatis memperlakukan bilangan bulat apa pun dengan nol di depannya sebagai oktal. Jadi os.chmod ("file", 484) (dalam desimal) akan memberikan hasil yang sama.

Apa yang Anda lakukan adalah lewat 664yang dalam oktal1230

Dalam kasus Anda, Anda akan membutuhkannya

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

[Pembaruan] Catatan, untuk Python 3 Anda memiliki awalan dengan 0o (nol oh). MISALNYA,0o666


1
Terima kasih, tetapi saya masih bingung bahwa, 484 dalam desimal berarti 744 dalam oktal, yang masuk akal di utas yang Anda sebutkan di forum. Namun, jika saya memberikan 644 dalam desimal, hasilnya 1204 dalam oktal. Bagaimana 1204 berhubungan dengan 230 dalam oktal?
AplusG

2
@AplusG: yang 1ini tidak dibuang! Itu adalah bit sticky / setuid / setgid, dan 1 artinya sticky. Menggunakan ls -lAnda mungkin melihat izin sekarang termasuk Tpada akhirnya ...
MestreLion

2
lebih mudah untuk menambahkan 0 dan menjadikannya oktal :)
radtek

10
Catatan, untuk Python 3 Anda memiliki awalan dengan 0o (nol oh).
Mawg mengatakan memulihkan Monica

1
Saya menggunakan 0o di python 2.7.10
Wyrmwood

125

Jadi bagi orang yang menginginkan semantik mirip dengan:

$ chmod 755 somefile

Menggunakan:

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

Jika Python Anda lebih tua dari 2.6:

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

12
Format python3 juga berfungsi di python 2.7.9. Saya belum memeriksa versi sebelumnya.
Fred Mitchell

3
Sintaks Python 3 bekerja kembali ke Python 2.6 docs.python.org/3/whatsnew/…
Pete

Bekerja untuk saya tks!
LandiLeite

Seharusnya begitu 00755, hanya untuk memperjelas ke mana suid / sgid / sticky bits pergi, jika beberapa pengembang kemudian datang dan ingin menggunakan skrip lama ini, misalnya, sgid dengan 2755tetapi kemudian tidak tahu mengapa perms benar-benar kacau. ;)
dannysauer

10

leading 0artinya ini adalah konstanta oktal , bukan desimal. dan Anda memerlukan oktal untuk mengubah mode file.

hak akses yang sedikit masker, misalnya, rwxrwx---adalah 111111000dalam biner, dan itu sangat mudah untuk kelompok bit dengan 3 untuk mengkonversi ke oktal, daripada menghitung representasi desimal.

0644(oktal) 0.110.100.100dalam biner (saya telah menambahkan titik agar terbaca), atau, seperti yang dapat Anda hitung, 420dalam desimal.


5

Gunakan simbol izin alih-alih angka

Masalah Anda akan terhindarkan jika Anda menggunakan simbol izin yang diberi nama secara lebih semantik daripada angka ajaib mentah, misalnya untuk 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
)

Ini didokumentasikan di https://docs.python.org/3/library/os.html#os.chmod dan namanya sama dengan nilai API C POSIX yang didokumentasikan di man 2 stat.

Keuntungan lainnya adalah portabilitas yang lebih besar seperti yang disebutkan dalam dokumen:

Catatan: Meskipun Windows mendukung chmod(), Anda hanya dapat menyetel flag file hanya-baca dengannya (melalui konstanta stat.S_IWRITEdan stat.S_IREADatau nilai integer yang sesuai). Semua bit lainnya diabaikan.

chmod +xditunjukkan di: Bagaimana Anda melakukan "chmod + x" sederhana dari dalam python?

Diuji di Ubuntu 16.04, Python 3.5.2.


1
Ini adalah cara yang benar untuk mengatasi masalah tersebut.
carthurs

Saya tahu ini dengan cara python tetapi hampir tidak bisa lebih buruk lagi :)
Tomasz Swider

2

Jika Anda memiliki izin yang diinginkan disimpan ke string, lakukan

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

0

Menggunakan stat. * Bit mask menurut saya merupakan cara paling portabel dan eksplisit untuk melakukan ini. Namun di sisi lain, saya sering lupa cara terbaik untuk mengatasinya. Jadi, berikut adalah contoh untuk menutupi izin 'grup' dan 'lainnya' dan membiarkan izin 'pemilik' tidak tersentuh. Menggunakan bitmask dan pengurangan adalah pola yang berguna.

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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.