在子进程中使用*通配符的命令问题 [英] Problems with command using * wildcard in subprocess

查看:75
本文介绍了在子进程中使用*通配符的命令问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用子进程库和Popen方法将文件从一个位置复制到另一位置。运行以下脚本时,出现错误 cp:无法统计/ some / dev_path / * 。有人告诉我 * 不会扩展到文件名,这就是问题所在。同样在其他一些帖子中,有人建议使用call而不是Popen,但就我所知,call不会返回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的禅宗),并且不易出错。处理错误要干净得多,您会得到很好的异常,包括一系列错误(例如这样,您就不必处理产生子流程并与之进行通讯了;其次,如果不需要的话,分叉子流程是不必要的资源浪费。其他问题包括引号/如果您未能正确清理用户输入内容,就可以避免转义并可能在代码中引入安全漏洞。)

(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.

这篇关于在子进程中使用*通配符的命令问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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