web-dev-qa-db-fra.com

Comment faites-vous un simple "chmod + x" depuis python?

Je souhaite créer un fichier à partir d'un script python exécutable.

import os
import stat
os.chmod('somefile', stat.S_IEXEC)

il apparaît que os.chmod n'ajoute pas les permissions comme unix chmod le fait. Avec la dernière ligne commentée, le fichier a le filemode -rw-r--r--, sans commentaire, le mode de fichier est ---x------. Comment puis-je simplement ajouter le drapeau u+x tout en conservant intact le reste des modes?

92
priestc

Utilisez os.stat() pour obtenir les autorisations en cours, utilisez | pour ou les bits ensemble et utilisez os.chmod() pour définir les autorisations mises à jour.

Exemple:

import os
import stat

st = os.stat('somefile')
os.chmod('somefile', st.st_mode | stat.S_IEXEC)
151

Pour les outils générant des fichiers exécutables (scripts, par exemple), le code suivant peut être utile:

def make_executable(path):
    mode = os.stat(path).st_mode
    mode |= (mode & 0o444) >> 2    # copy R bits to X
    os.chmod(path, mode)

Cela permet (plus ou moins) de respecter la umask qui était en vigueur lors de la création du fichier: L'exécutable est uniquement défini pour ceux qui peuvent lire.

Usage:

path = 'foo.sh'
with open(path, 'w') as f:           # umask in effect when file is created
    f.write('#!/bin/sh\n')
    f.write('echo "hello world"\n')

make_executable(path)
15

Si vous connaissez les autorisations souhaitées, l'exemple suivant peut vous aider à faire simple.

Python 2:

os.chmod("/somedir/somefile", 0775)

Python 3:

os.chmod("/somedir/somefile", 0o775)

Compatible avec soit (conversion octale):

os.chmod("/somedir/somefile", 509)

référence exemples d'autorisations

4
zerocog

Vous pouvez aussi faire ça

>>> import os
>>> st = os.stat("hello.txt")

Liste actuelle du fichier

$ ls -l hello.txt
-rw-r--r--  1 morrison  staff  17 Jan 13  2014 hello.txt

Maintenant, fais ça.

>>> os.chmod("hello.txt", st.st_mode | 0o111)

et vous verrez ceci dans le terminal.

ls -l hello.txt    
-rwxr-xr-x  1 morrison  staff  17 Jan 13  2014 hello.txt

Vous pouvez utiliser bit à bit ou avec 0o111 pour rendre tous les exécutables, 0o222 pour rendre toutes les écritures et 0o444 pour les rendre lisibles. 

2
ncmathsadist

Respectez umask comme chmod +x

man chmod dit que si augo n'est pas donné comme dans:

chmod +x mypath

alors a est utilisé par avec umask:

Une combinaison des lettres ugoa détermine quels accès des utilisateurs au fichier sera modifié: l’utilisateur qui en est propriétaire (u), les autres utilisateurs du groupe du fichier (g), les autres utilisateurs ne figurant pas dans le groupe du fichier (o) ou tous utilisateurs (a). Si aucun de ces éléments n'est fourni, l'effet est le même que si (a) était donné, mais les bits définis dans l'umask ne sont pas affectés.

Voici une version qui simule exactement ce comportement:

#!/usr/bin/env python3

import os
import stat

def get_umask():
    umask = os.umask(0)
    os.umask(umask)
    return umask

def chmod_plus_x(path):
    os.chmod(
        path,
        os.stat(path).st_mode |
        (
            (
                stat.S_IXUSR |
                stat.S_IXGRP |
                stat.S_IXOTH
            )
            & ~get_umask()
        )
    )

chmod_plus_x('.gitignore')

Voir aussi: Comment puis-je obtenir les autorisations de fichier par défaut en Python?

Testé sous Ubuntu 16.04, Python 3.5.2.

En python3:

import os
os.chmod("somefile", 0o664)

N'oubliez pas d'ajouter le préfixe 0o, car les autorisations sont définies en tant qu'entier octal et que Python traite automatiquement tout entier avec un zéro à gauche comme un octal. Sinon, vous passez bien os.chmod("somefile", 1230), qui est octal de 664.

0
funk1d

Si vous utilisez Python 3.4+, vous pouvez utiliser le fichier pratique pathlib de la bibliothèque standard.

Sa classe Path a des méthodes intégrées chmod et stat .

from pathlib import Path


f = Path("/path/to/file.txt")
f.chmod(f.stat().st_mode | stat.S_IEXEC)
0
cs01