我试图使用子进程调用来执行复制操作(下面的代码):
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
选项,这对我来说并不像我提到的那样:(
答案 0 :(得分:16)
使用shell=True
时,请将字符串而不是列表传递给subprocess.call
:
subprocess.call('cp -r ./testdir1/* ./testdir2/', shell=True)
在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/'])