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

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

问题描述

我正在尝试使用子进程库和 Popen 方法将文件从一个位置复制到另一个位置.运行以下脚本时,我收到错误 cp: cannot stat/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.

但是,对于这种情况,我强烈建议改用 shutil.copytree.

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天全站免登陆