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?

AplusG
sumber
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

RedBaron
sumber
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)"
Dima
sumber
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.

lenik
sumber
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.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
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))
mc.dev
sumber
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)
Jason Drew
sumber