Comment utiliser la commande mv en Python avec subprocess

j'ai beaucoup de fichiers dans /home/somedir/subdir/ et je suis en train de les déplacer jusqu'à /home/somedir par programmation.

en ce moment j'ai ceci:

subprocess.call(["mv", "/home/somedir/subdir/*", "somedir/"])

mais il me donne cette erreur:

mv: cannot stat `/home/somedir/subdir/*': No such file or directory

je sais qu'il existe parce que quand je tape la commande mv à la main en utilisant la même commande que le script utilise il fonctionne parfaitement.

8
demandé sur CSStudent 2014-02-16 03:09:17

3 réponses

si vous appelez le sous-processus de cette façon:

subprocess.call(["mv", "/home/somedir/subdir/*", "somedir/"])

vous donnez en fait l'argument /home/somedir/subdir/* à la commande mv , avec un fichier * . c'est-à-dire que vous essayez en fait de déplacer le fichier * .

subprocess.call("mv /home/somedir/subdir/* somedir/", shell=True)

il utilisera le shell qui développera le premier argument.

Nota Bene : lorsque vous utilisez l'argument shell=True vous devez changer votre liste d'arguments dans une chaîne qui sera donnée à l'interpréteur de commandes.

indice : vous pouvez également utiliser les fonctions os.rename() ou shutil.move() , ainsi que os.path.walk() ou os.listdir() pour déplacer les fichiers vers la destination d'une manière plus pythonique.

12
répondu zmo 2014-02-15 23:18:18

vous pouvez résoudre cela en ajoutant le paramètre shell=True , pour prendre en compte les caractères génériques dans votre cas (et donc écrire la commande directement, sans aucune liste):

subprocess.call("mv /home/somedir/subdir/* somedir/", shell=True)

sans lui, l'argument est directement donné à la commande mv avec l'astérisque. C'est la tâche shell de retourner tous les fichiers qui correspondent au motif en général.

2
répondu Maxime Lorant 2014-02-15 23:12:29

vous utilisez le globbing shell * , et vous attendez à ce que la commande mv sache ce que cela signifie. Vous pouvez obtenir la même erreur à partir d'une commande shell de cette façon:

$ mv 'somedir/subdir/*' ...

notez les citations. Le shell n'est généralement glob-matching sur * pour vous, mais les commandes ne le faisons pas sur leurs lignes de commande; pas même un shell. Il y a une fonction de bibliothèque C appelée fnmatch qui fait des globbings de style shell pour vous, que chaque langage de programmation copie plus ou moins. Il pourrait même avoir le même nom en Python. Ou il pourrait y avoir le mot "glob" dedans; Je ne me souviens pas.

2
répondu jpaugh 2014-02-15 23:12:31