使用“cp”时的Python子进程错误

时间:2013-07-26 12:04:04

标签: python subprocess cp

我试图使用子进程调用来执行复制操作(下面的代码):

import subprocess
pr1 = subprocess.call(['cp','-r','./testdir1/*','./testdir2/'], shell = True)

我得到一个错误说:

cp: missing file operand

Try `cp --help' for more information.

当我尝试shell=False时,我得到了

cp: cannot stat `./testdir1/*': No such file or directory

如何解决这个问题?

我正在使用RedHat Linux GNOME Deskop版本2.16.0以及bash shell和Python 2.6

P.S。我阅读了Problems with issuing cp command with Popen in Python中发布的问题,并建议使用shell = True选项,这对我来说并不像我提到的那样:(

3 个答案:

答案 0 :(得分:16)

使用shell=True时,请将字符串而不是列表传递给subprocess.call

subprocess.call('cp -r ./testdir1/* ./testdir2/', shell=True)

The docs say

  

在Unix上,shell = True,shell默认为/ bin / sh。如果args是   string,string指定通过shell执行的命令。   这意味着字符串必须完全按照原样进行格式化   在shell提示符下键入时。这包括,例如,引用或   反斜杠转义文件名,其中包含空格。如果args是   sequence,第一项指定命令字符串,以及任何   其他项目将被视为shell的附加参数   本身。

所以(在Unix上),当列表传递给subprocess.Popen(或subprocess.call)时,列表的第一个元素被解释为命令,列表中的所有其他元素都被解释作为 shell 的参数。因为在你的情况下你不需要将参数传递给shell,你可以只传递一个字符串作为第一个参数。

答案 1 :(得分:4)

现在这是一个旧线程,但我遇到了同样的问题。

您通过此次通话遇到的问题:

cp '-r' './testdir1/*' './testdir2/'

是引用第一个参数之后的每个参数。所以shell看到这样的命令:

*

问题在于通配符(*)。文件系统查找文字名称为' testdir1'的文件。在shell = True目录中,当然不在那里。

解决方案是使用{{1}}选项调用所选答案,而不是引用任何参数。

答案 2 :(得分:1)

我知道 shell=True 的选项可能很诱人,但由于 here,它总是不可取的。相反,您可以使用 subprocess 和 glob 模块的组合。

对于 Python 3.5 或更高版本

import subprocess
import glob

subprocess.run(['cp', '-r'] + glob.glob('./testdir1/*') + ['./testdir2/'])

对于 Python 3.4 或更低版本

import subprocess
import glob

subprocess.call(['cp', '-r'] + glob.glob('./testdir1/*') + ['./testdir2/'])