Il modulo Python os.chmod (file, 664) non cambia il permesso in rw-rw-r— ma -w - wx ----


111

Recentemente sto usando il sistema operativo del modulo Python, quando ho provato a cambiare il permesso di un file, non ho ottenuto il risultato atteso. Ad esempio, intendevo modificare l'autorizzazione in rw-rw-r--,

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

Il permesso di proprietà è in realtà -w - wx --- (230)

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

Tuttavia, se cambio 664 in 0664 nel codice, il risultato è proprio quello di cui ho bisogno, ad es

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

Il risultato è:

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

Qualcuno potrebbe aiutare a spiegare perché lo 0 iniziale è così importante per ottenere il risultato corretto?


33
Ottale. Ottale. Ottale.
Cole Johnson,

6
Ho aperto un problema per la documentazione di Python su bugs.python.org/issue25377 perché dovrebbe essere chiaro dalla documentazione.
Karl Richter

Risposte:


130

Trovato su un forum diverso

Se ti stai chiedendo perché quello zero iniziale è importante, è perché i permessi sono impostati come un numero intero ottale e Python tratta automagicamente qualsiasi numero intero con uno zero iniziale come ottale. Quindi os.chmod ("file", 484) (in decimale) darebbe lo stesso risultato.

Quello che stai facendo è passare 664che in ottale è1230

Nel tuo caso avresti bisogno

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

[Aggiorna] Nota, per Python 3 hai il prefisso 0o (zero oh). PER ESEMPIO,0o666


1
Grazie, ma sono ancora confuso che, 484 in decimale significa 744 in ottale, il che ha senso nel thread che hai citato nel forum. Tuttavia, se do 644 in decimale, va a 1204 in ottale. Che relazione c'è tra 1204 e 230 in ottale?
AplusG

2
@AplusG: il non1 viene scartato! Questo è il bit sticky / setuid / setgid e 1 significa . Usando potresti notare che le autorizzazioni ora includono un alla fine ...stickyls -lT
MestreLion

2
più facile aggiungere lo 0 e renderlo ottale :)
radtek

10
Nota, per Python 3 hai il prefisso 0o (zero oh).
Mawg dice di reintegrare Monica il

1
Uso 0o in Python 2.7.10
Wyrmwood

125

Quindi per le persone che vogliono una semantica simile a:

$ chmod 755 somefile

Uso:

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

Se il tuo Python è più vecchio di 2.6:

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

12
Il formato python3 funziona anche in python 2.7.9. Non ho controllato le versioni precedenti.
Fred Mitchell

3
La sintassi di Python 3 funziona di nuovo con Python 2.6 docs.python.org/3/whatsnew/…
Pete

Lavora per me tks!
LandiLeite

Probabilmente dovrebbe essere 00755, solo per chiarire dove vanno i bit suid / sgid / sticky, nel caso in cui qualche sviluppatore successivo arrivi e voglia utilizzare questo vecchio script, ad esempio sgid con 2755ma poi non riesce a capire perché le permanenti sono completamente rovinate. ;)
dannysauer

10

leading 0significa che questa è una costante ottale , non quella decimale. e hai bisogno di un ottale per cambiare la modalità file.

i permessi sono una maschera di bit, ad esempio, rwxrwx---è 111111000in binario, ed è molto facile raggruppare i bit per 3 per convertirli in ottale, piuttosto che calcolare la rappresentazione decimale.

0644(ottale) è 0.110.100.100in binario (ho aggiunto punti per la leggibilità) o, come puoi calcolare, 420in decimale.


5

Utilizza i simboli di autorizzazione invece dei numeri

Il tuo problema sarebbe stato evitato se avessi usato i simboli di autorizzazione con nomi più semantici anziché i numeri magici grezzi, ad esempio per 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
)

Questo è documentato su https://docs.python.org/3/library/os.html#os.chmod ei nomi sono gli stessi dei valori API POSIX C documentati in man 2 stat.

Un altro vantaggio è la maggiore portabilità come menzionato nei documenti:

Nota: sebbene Windows supporti chmod(), è possibile impostare solo il flag di sola lettura del file con esso (tramite le costanti stat.S_IWRITEe stat.S_IREADo un valore intero corrispondente). Tutti gli altri bit vengono ignorati.

chmod +xè dimostrato in: Come si esegue un semplice "chmod + x" da Python?

Testato in Ubuntu 16.04, Python 3.5.2.


1
Questo è il modo corretto di affrontare il problema.
carthurs

Lo so alla maniera del pitone ma difficilmente potrebbe essere più brutto :)
Tomasz Swider

2

Se hai i permessi desiderati salvati nella stringa, fallo

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

0

L'utilizzo delle maschere stat. * Bit mi sembra il modo più portabile ed esplicito per farlo. Ma d'altra parte, spesso dimentico come gestirlo al meglio. Quindi, ecco un esempio di mascherare i permessi "gruppo" e "altro" e lasciare intatti i permessi "proprietario". Usare maschere di bit e sottrazione è un modello utile.

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.