سؤال

I have a lot of files in /home/somedir/subdir/ and I'm trying to move them all up to /home/somedir programmatically.

right now I have this:

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

but it's giving me this error:

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

I know that it does exist because when I type the mv command by hand using the exact same command as the script uses it works perfectly.

هل كانت مفيدة؟

المحلول

if you call subprocess that way:

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

you're actually giving the argument /home/somedir/subdir/* to the mv command, with an actual * file. i.e. you're actually trying to move the * file.

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

it will use the shell that will expand the first argument.

Nota Bene: when using the shell=True argument you need to change your argument list into a string that will be given to the shell.

Hint: You can also use the os.rename() or shutil.move() functions, along with os.path.walk() or os.listdir() to move the files to destination in a more pythonic way.

نصائح أخرى

You can solve this by adding the parameter shell=True, to take into account wildcards in your case (and so write the command directly, without any list):

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

Without it, the argument is directly given to the mv command with the asterisk. It's the shell job to return every files which match the pattern in general.

You are using shell globbing *, and expecting the mv command to know what it means. You can get the same error from a command shell this way:

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

Notice the quotes. The shell usually does glob-matching on * for you, but commands don't do that on their command lines; not even a shell does. There is a C library function called fnmatch that does shell-style globbing for you, which every programming language more or less copies. It might even have the same name in Python. Or it might have the word "glob" in it; I don't remember.

Here's a simple way to work with subprocess 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()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top