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.
You are using shell globbing
*
, and expecting themv
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 calledfnmatch
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.if you call subprocess that way:
you're actually giving the argument
/home/somedir/subdir/*
to themv
command, with an actual*
file. i.e. you're actually trying to move the*
file.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()
orshutil.move()
functions, along withos.path.walk()
oros.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):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.