Python子进程在使用时出错";cp";

Python子进程在使用时出错";cp";,python,subprocess,cp,Python,Subprocess,Cp,我试图使用子流程调用执行复制操作(代码如下): 我的错误是: 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

我试图使用子流程调用执行复制操作(代码如下):

我的错误是:

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


另外,我阅读了中发布的问题,它建议使用
shell=True
选项,正如我提到的那样,该选项对我不起作用:(

当使用
shell=True
时,将字符串而不是列表传递给
子流程。调用

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

在shell=True的Unix上,shell默认为/bin/sh 字符串,该字符串指定要通过shell执行的命令。 这意味着字符串的格式必须与实际格式完全相同 当在shell提示符下键入时。这包括,例如,引用或 反斜杠转义文件名,其中包含空格。如果args是 顺序,第一项指定命令字符串,以及 附加项将被视为shell的附加参数 本身


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

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

您在此呼叫中遇到的问题:

subprocess.call(['cp','-r','./testdir1/*','./testdir2/'], shell = False)
第一个参数之后的每个参数都被引用。因此,对于shell,可以看到如下命令:

cp '-r' './testdir1/*' './testdir2/'
问题是通配符(
*
)。文件系统在
testdir1
目录中查找一个文本名为“
*
”的文件,当然,该目录不存在


解决方案是使用
shell=True
选项进行与所选答案类似的调用,并且不使用任何引用的参数。

我知道
shell=True
选项可能很诱人,但由于以下原因,它始终是不可取的。相反,您可以使用子流程和全局模块的组合

对于Python 3.5或更高版本

import subprocess
import glob

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

subprocess.call(['cp', '-r'] + glob.glob('./testdir1/*') + ['./testdir2/'])
对于Python 3.4或更低版本

import subprocess
import glob

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

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

很好的解释。帮助我理解发生了什么。如果我想做这样的调用:
subprocess.call([“cp”、“-r”、“/home/user/logs”、directory\u logs])
where
directory\u logs
是一个字符串,其中我有一个现有目录。在这种情况下,我如何使用
shell=True
选项?由于以下原因,强烈反对使用
shell=True
选项。我在下面发布了一个更安全的选项。