Déterminer si un répertoire est accessible en écriture

Quelle serait la meilleure façon de déterminer si un répertoire est accessible en écriture pour l’utilisateur exécutant le script? Comme cela impliquera probablement l’utilisation du module os, je devrais mentionner que je l’exécute dans un environnement * nix.

Bien que Christophe suggère une solution plus Pythonique, le module os a la fonction os.access pour vérifier l’access:

os.access('/path/to/folder', os.W_OK) # W_OK est pour l’écriture, R_OK pour la lecture, etc.

Cela peut sembler étrange de suggérer cela, mais un langage Python commun est

Il est plus facile de demander le pardon que la permission

Suivant cet idiome, on pourrait dire:

Essayez d’écrire dans le répertoire en question et détectez l’erreur si vous n’êtes pas autorisé à le faire.

Ma solution utilisant le module tempfile :

 import tempfile import errno def isWritable(path): try: testfile = tempfile.TemporaryFile(dir = path) testfile.close() except OSError as e: if e.errno == errno.EACCES: # 13 return False e.filename = path raise return True 

Trébuché sur ce fil à la recherche d’exemples pour quelqu’un. Premier résultat sur Google, félicitations!

Les gens parlent de la manière Pythonic de le faire dans ce thread, mais pas d’exemples de code simples? Voilà, pour quiconque trébuche dans:

 import sys filepath = 'C:\\path\\to\\your\\file.txt' try: filehandle = open( filepath, 'w' ) except IOError: sys.exit( 'Unable to write to file ' + filepath ) filehandle.write("I am writing this text to the file\n") 

Cela tente d’ouvrir un descripteur de fichier pour l’écriture, et quitte avec une erreur si le fichier spécifié ne peut pas être écrit: Ceci est beaucoup plus facile à lire et constitue une bien meilleure façon de procéder que de faire des vérifications sur le chemin du fichier ou le répertoire. , car il évite les conditions de course; les cas où le fichier devient impossible à écrire entre le moment où vous exécutez le précontrôle et le moment où vous essayez réellement d’écrire dans le fichier.

Si vous ne vous souciez que du fichier os.access(path, os.W_OK) , os.access(path, os.W_OK) devrait faire ce que vous demandez. Si vous voulez plutôt savoir si vous pouvez écrire dans le répertoire, open() un fichier de test pour l’écrire (il ne devrait pas exister auparavant), attrapez et examinez toute IOError et nettoyez ensuite le fichier de test.

Plus généralement, pour éviter les attaques TOCTOU (seulement un problème si votre script s’exécute avec des privilèges élevés – suid ou cgi ou plus), vous ne devriez pas vraiment faire confiance à ces tests préalables, mais supprimer les privilèges, open() , et attendez-vous à l’ IOError .

Vérifiez les bits de mode:

 def isWritable(name): uid = os.geteuid() gid = os.getegid() s = os.stat(dirname) mode = s[stat.ST_MODE] return ( ((s[stat.ST_UID] == uid) and (mode & stat.S_IWUSR)) or ((s[stat.ST_GID] == gid) and (mode & stat.S_IWGRP)) or (mode & stat.S_IWOTH) ) 

Voici ce que j’ai créé sur la base de la réponse de ChristopheD:

 import os def isWritable(directory): try: tmp_prefix = "write_tester"; count = 0 filename = os.path.join(directory, tmp_prefix) while(os.path.exists(filename)): filename = "{}.{}".format(os.path.join(directory, tmp_prefix),count) count = count + 1 f = open(filename,"w") f.close() os.remove(filename) return True except Exception as e: #print "{}".format(e) return False directory = "c:\\" if (isWritable(directory)): print "directory is writable" else: print "directory is not writable" 
  if os.access(path_to_folder, os.W_OK) is not True: print("Folder not writable") else : print("Folder writable") 

plus d’informations sur l’access peuvent être trouvés ici

Si vous devez vérifier la permission d’ un autre utilisateur (oui, je réalise que cela contredit la question, mais peut être utile pour quelqu’un), vous pouvez le faire via le module pwd et les bits de mode du répertoire.

Disclaimer – ne fonctionne pas sous Windows, car il n’utilise pas le modèle d’permissions POSIX (et le module pwd n’y est pas disponible), par exemple une solution uniquement pour les systèmes * nix.

Notez qu’un répertoire doit avoir tous les 3 bits définis – Read, Write et eXecute.
Ok, R n’est pas un must absolu, mais sans cela, vous ne pouvez pas lister les entrées dans le répertoire (vous devez donc connaître leur nom). Exécuter en revanche est absolument nécessaire – sans cela, l’utilisateur ne peut pas lire les inodes du fichier; donc même avoir W, sans fichiers X ne peut pas être créé ou modifié. Explication plus détaillée sur ce lien.

Enfin, les modes sont disponibles dans le module stat , leurs descriptions sont dans inode (7) man .

Exemple de code comment vérifier:

 import pwd import stat import os def check_user_dir(user, directory): dir_stat = os.stat(directory) user_id, group_id = pwd.getpwnam(user).pw_uid, pwd.getpwnam(user).pw_gid directory_mode = dir_stat[stat.ST_MODE] # use directory_mode as mask if user_id == dir_stat[stat.ST_UID] and stat.S_IRWXU & directory_mode == stat.S_IRWXU: # owner and has RWX return True elif group_id == dir_stat[stat.ST_GID] and stat.S_IRWXG & directory_mode == stat.S_IRWXG: # in group & it has RWX return True elif stat.S_IRWXO & directory_mode == stat.S_IRWXO: # everyone has RWX return True # no permissions return False