J'essaie de copier /home/myUser/dir1/
et tout son contenu (et son contenu, etc.) à /home/myuser/dir2/
en python. De plus, je veux que la copie écrase tout dans dir2/
.
Il ressemble à distutils.dir_util.copy_tree
pourrait être le bon outil pour ce travail, mais il n’est pas certain qu’il existe quelque chose de plus facile/plus évident à utiliser pour une tâche aussi simple.
Si c'est le bon outil, comment puis-je l'utiliser? Selon le docs , il faut 8 paramètres. Dois-je réussir tous les 8 ne sont que src
, dst
et update
, et si oui, comment (je suis nouveau en Python).
S'il y a quelque chose de mieux à faire, quelqu'un peut-il me donner un exemple et me diriger dans la bonne direction? Merci d'avance!
Vous pouvez utiliser distutils.dir_util.copy_tree
_ . Cela fonctionne très bien et vous n’avez pas à passer tous les arguments, seuls src
et dst
sont obligatoires.
Cependant, dans votre cas, vous ne pouvez pas utiliser un outil similaire, tel que shutil.copytree
_ car il se comporte différemment: comme le répertoire de destination ne doit pas exister, cette fonction ne peut pas être utilisée pour écraser son contenu.
Si vous souhaitez utiliser l'outil cp
comme suggéré dans la question, veuillez noter que l'utilisation du module subprocess
est actuellement la méthode recommandée pour générer de nouveaux processus, comme vous pouvez le voir dans la section documentation de la fonction os.system .
Jetez un coup d'œil au paquet shutil
, en particulier rmtree
et copytree
. Vous pouvez vérifier si un fichier/chemin existe avec os.paths.exists(<path>)
.
import shutil
import os
def copy_and_overwrite(from_path, to_path):
if os.path.exists(to_path):
shutil.rmtree(to_path)
shutil.copytree(from_path, to_path)
Vincent avait raison sur le fait que copytree
ne fonctionnait pas, si les répertoires existent déjà. Donc, distutils
est la version la plus intéressante. Vous trouverez ci-dessous une version corrigée de shutil.copytree
. Il est fondamentalement copié 1-1, sauf le premier os.makedirs()
placé derrière une construction if-else-:
import os
from shutil import *
def copytree(src, dst, symlinks=False, ignore=None):
names = os.listdir(src)
if ignore is not None:
ignored_names = ignore(src, names)
else:
ignored_names = set()
if not os.path.isdir(dst): # This one line does the trick
os.makedirs(dst)
errors = []
for name in names:
if name in ignored_names:
continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
Elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore)
else:
# Will raise a SpecialFileError for unsupported file types
copy2(srcname, dstname)
# catch the Error from the recursive copytree so that we can
# continue with other files
except Error, err:
errors.extend(err.args[0])
except EnvironmentError, why:
errors.append((srcname, dstname, str(why)))
try:
copystat(src, dst)
except OSError, why:
if WindowsError is not None and isinstance(why, WindowsError):
# Copying file access times may fail on Windows
pass
else:
errors.extend((src, dst, str(why)))
if errors:
raise Error, errors
Voici une solution simple pour écraser récursivement une destination avec une source, en créant les répertoires nécessaires au fur et à mesure. Cela ne gère pas les liens symboliques, mais ce serait une simple extension (voir la réponse de @Michael ci-dessus).
def recursive_overwrite(src, dest, ignore=None):
if os.path.isdir(src):
if not os.path.isdir(dest):
os.makedirs(dest)
files = os.listdir(src)
if ignore is not None:
ignored = ignore(src, files)
else:
ignored = set()
for f in files:
if f not in ignored:
recursive_overwrite(os.path.join(src, f),
os.path.join(dest, f),
ignore)
else:
shutil.copyfile(src, dest)