在Python中使用Popen发出cp命令的问题 [英] Problems with issuing cp command with Popen in Python

查看:640
本文介绍了在Python中使用Popen发出cp命令的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to copy files from one location to another using subprocess library and Popen method. When runing following script I'm getting the error cp: cannot stat /some/dev_path/*. I was told that the * is not expanded to the file names and that's where the problem is. Also in some other posts people were suggesting to use call instead of Popen, but call will not return stderr as far as I know.

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

Expanding the * (globbing) is a function of your shell, bash for example. Therefore you'd have to use the keyword argument shell=True in your subprocess.Popen call.

但是,对于这种情况,我强烈建议您使用

However, for this case I'd strongly suggest to use shutil.copytree instead.

(首先,因为它更简单(参见 Python的禅修),并且不太容易出错。处理错误更加干净,你会得到很好的异常包括错误列表多文件操作,像你的),你不必处理生成一个子进程和它的沟通第二,如果你不需要,这是一个不必要的浪费资源fork子进程,其他问题包括引用/如果您未能正确清理用户输入,则可能会泄露并可能将安全漏洞导入您的代码中。)

(First of all, because it's much simpler (see Zen of Python) and less error-prone. Dealing with errors is much cleaner, you get nice exceptions including a list of errors (for multi file operations like yours), and you don't have to deal with spawning a subprocess and communicating with it. Second, it's an unnecessary waste of resources to fork a child process if you don't need to. Other issues include quoting / escaping and possibly introducing security vulnerabilities into your code if you fail to properly sanitize user input.)

例如:

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.path.join()。这将为当前操作系统使用正确的目录分隔符( os.sep ),并允许您轻松编写可移植代码。

Also, you shouldn't build filesystem paths by concatenating strings together, but instead use os.path.join(). That will use the correct directory separator (os.sep) for the current OS and allow you to easily write portable code.

示例:

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

注意: os.path.join 仍然只有(智能)字符串操作 - 可访问或甚至存在。

Note: os.path.join still only does (smart) string manipulation - it doesn't care if that path is accessible or even exists.

这篇关于在Python中使用Popen发出cp命令的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆