如何在Python中使用mv命令和子进程

时间:2014-02-15 23:09:18

标签: python unix subprocess stat mv

我在/ home / somedir / subdir /中有很多文件,我试图以编程方式将它们全部移到/ home / somedir。

现在我有这个:

subprocess.call(["mv", "/home/somedir/subdir/*", "somedir/"])

但它给了我这个错误:

mv: cannot stat `/home/somedir/subdir/*': No such file or directory

我知道它确实存在,因为当我使用与脚本使用完全相同的命令手动输入mv命令时,它可以很好地工作。

4 个答案:

答案 0 :(得分:12)

如果以这种方式调用子进程:

subprocess.call(["mv", "/home/somedir/subdir/*", "somedir/"])

您实际上是将/home/somedir/subdir/*参数赋予mv命令,并使用实际的*文件。即你实际上是在尝试移动*文件。

subprocess.call("mv /home/somedir/subdir/* somedir/", shell=True)

它将使用将扩展第一个参数的shell。

Nota Bene :使用shell=True参数时,您需要将参数列表更改为将提供给shell的字符串。

提示:您还可以使用os.rename()shutil.move()函数以及os.path.walk()os.listdir()将文件移至目标位置一种更加pythonic的方式。

答案 1 :(得分:2)

你可以通过添加参数shell=True来解决这个问题,在你的情况下考虑通配符(所以直接编写命令,没有任何列表):

subprocess.call("mv /home/somedir/subdir/* somedir/", shell=True)

没有它,该参数直接赋予带有星号的mv命令。一般来说,返回与模式匹配的每个文件都是shell作业。

答案 2 :(得分:2)

您正在使用shell globbing *,并希望mv命令知道它的含义。您可以通过以下方式从命令shell获取相同的错误:

$ mv 'somedir/subdir/*' ...

注意引号。 shell通常会为*执行全局匹配,但命令不会在命令行上执行此操作;甚至没有外壳。有一个名为fnmatch的C库函数可以为您执行shell样式的通函,每种编程语言都或多或少地复制。它甚至可能在Python中具有相同的名称。或者它可能有“glob”这个词;我不记得了。

答案 3 :(得分:0)

这是使用子流程Popen的简单方法

import subprocess
import os

class FolderCommands:
    src = None
    dst = None

    def __init__(self, src, dst):
        self.src = src
        self.dst = dst

    def move(self):
        listOfFiles = os.listdir(self.src)
        print(listOfFiles)
        modify_src = self.src.replace(" ", "\ ")
        dst = self.dst.replace(" ", "\ ")
        for f in listOfFiles:
            #Attaching the filename at the end of the src path

            fullPath = modify_src + "/'" + f +"'"
            subprocess.Popen("mv" + " " + fullPath + " " + dst, shell=True)

obj = FolderCommands(input("Enter Source path"), input("Enter Destination path"))
obj.move()