J'étais un peu accro au sous-processus, alors j'ai pris une note.
Un traitement équivalent à cp -pr était requis lors de la création d'un script d'assistance pour le déploiement. L'implémentation cp (incomplète) écrite en Python est la suivante.
python_cp
def _copy(src, dst):
if os.path.isfile(src):
shutil.copy2(src, dst)
return
if os.path.isdir(src) and os.path.isdir(dst):
target = os.path.join(dst, os.path.basename(src))
# TODO Fix behavior like cp -pr (Si le répertoire cible existe, les fichiers qu'il contient/Le répertoire doit être conservé)
if os.path.exists(target):
shutil.rmtree(target)
shutil.copytree(src, target)
return
if os.path.isdir(src) and os.path.isfile(dst):
raise IOError(
"(Src:directory/Dest:file) This combination isn't allowed")
Bien qu'il existe des restrictions (voir les commentaires), ce cas ne peut pas se produire dans cette application, donc c'est OK.
Cependant, comme d'habitude, j'ai entendu l'illusion que "Wow, l'ingénieur (rires) qui ne le fait pas même si je peux déplacer cp avec Subprocess ..." du côté, j'ai donc décidé d'écrire une implémentation qui utilise le subprocess. ..
subprocess_cp_error
def _copy(src, dst):
subprocess.Popen(['cp', '-pr', src, dst]).communicate()
Cependant, avec cette implémentation, les caractères génériques ne peuvent pas être utilisés dans src. Pour interpréter le caractère générique, vous devez passer shell = True à Popen et exécuter la commande via le shell. http://docs.python.jp/2.7/library/subprocess.html#subprocess.Popen
subprocess_cp_error2
def _copy(src, dst):
subprocess.Popen(['cp', '-pr', src, dst], shell=True).communicate()
Alors, j'ai pensé: "Est-ce fini?", Mais ce n'est pas le cas. Avec l'implémentation ci-dessus, la commande cp ne fonctionne pas du tout. Lorsque shell = True, la commande est exécutée via le shell comme décrit ci-dessus, mais elle équivaut à la commande suivante.
via_shell_error
/bin/sh -c 'cp' '-pr' (src) (dst)
À première vue, cela a l'air bien, mais dans ce cas -pr n'est pas considéré comme une option pour cp, et src et dst ne sont pas considérés comme des arguments pour cp. En d'autres termes, cp a été exécuté sans aucun argument, ce qui a entraîné une erreur. Pour être correct, vous devez le spécifier avec une chaîne de caractères comme suit
via_shell
/bin/sh -c 'cp -pr (src) (dst)'
Ainsi, pour exécuter le sous-processus correspondant, spécifiez la commande donnée à Popen sous la forme d'une chaîne de caractères au lieu d'un tableau.
subprocess_cp
def _copy(src, dst):
subprocess.Popen('cp -pr {0} {1}'.format(src, dst), shell=True).communicate()
Ne devrait pas être shell = True si non nécessaire w Eh bien, en fait, cela provoque également une injection de shell, donc la référence de la bibliothèque indique également: "Lorsque vous utilisez une entrée externe, ne la définissez jamais sur True!" ...
Recommended Posts