Python 子流程中使用*通配符的命令出现问题

Python 子流程中使用*通配符的命令出现问题,python,copy,subprocess,cp,glob,Python,Copy,Subprocess,Cp,Glob,我正在尝试使用子流程库和Popen方法将文件从一个位置复制到另一个位置。当运行下面的脚本时,我得到一个错误cp:cannot stat/some/dev_path/*。有人告诉我,*没有扩展到文件名,这就是问题所在。在其他一些帖子中,人们建议使用call而不是Popen,但据我所知,call不会返回stderr devPath = '/some/dev_path/' productionPath = '/some/prod_path/' p = subprocess.Popen(['cp',

我正在尝试使用子流程库和Popen方法将文件从一个位置复制到另一个位置。当运行下面的脚本时,我得到一个错误
cp:cannot stat/some/dev_path/*
。有人告诉我,
*
没有扩展到文件名,这就是问题所在。在其他一些帖子中,人们建议使用call而不是Popen,但据我所知,call不会返回stderr

devPath = '/some/dev_path/'
productionPath = '/some/prod_path/'

p = subprocess.Popen(['cp', '-r', devPath + '*', productionPath], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
pout, perr = p.communicate()

if perr != '':
    sys.exit('Error: ' + perr)

扩展
*
(globbing)是shell的一个功能,例如bash。因此,您必须在
subprocess.Popen
调用中使用关键字参数
shell=True

然而,对于这种情况,我强烈建议使用

(首先,因为它更简单(请参阅)且更不容易出错。处理错误更简单,您可以获得包括错误列表在内的良好异常(对于像您这样的多文件操作),并且您不必处理生成子进程和与之通信的问题。其次,如果不需要,则派生子进程是不必要的资源浪费。其他问题包括引用/转义,如果您未能正确清理用户输入,则可能会在代码中引入安全漏洞。)

例如:

from shutil import copytree
from shutil import Error

try:
   copytree('dir_a', 'dir_b')
except (Error, OSError), e:
    print "Attempt to copy failed: %s" % e
此外,您不应该通过将字符串连接在一起来构建文件系统路径,而应该使用。这将为当前操作系统使用正确的目录分隔符(
os.sep
),并允许您轻松编写可移植代码

例如:

>>> import os
>>> os.path.join('/usr/lib', 'python2.7')
'/usr/lib/python2.7'

注意:
os.path.join
仍然只执行(智能)字符串操作-它不关心该路径是否可访问或是否存在。

扩展“*”是您使用的任何shell的函数,除非您在此处不使用shell。有关添加shell功能的几种方法,请参阅。为什么不改用
shutil.copytree()
,这样您就有了一些不需要子进程的可移植功能?Python使用shutil和glob模块对此提供了内置支持。您实际上不需要调用子流程。感谢您的回复。我不知道这是航天飞机。为什么shutil在这里比子流程更受欢迎?@marcin_koss更新了答案,解释了为什么要避免不必要的子流程。