2

I'm trying to write a simple program in Python that takes all the music files from my Downloads folder and puts them in my Music folder. I'm using Windows, and I can move the files using the cmd prompt, but I get this error:

WindowsError: [Error 2] The system cannot find the file specified

Here's my code:

#! /usr/bin/python

import os 
from subprocess import call

def main():
    os.chdir("C:\\Users\Alex\Downloads") #change directory to downloads folder

    suffix =".mp3"    #variable holdinng the .mp3 tag
    fnames = os.listdir('.')  #looks at all files

    files =[]  #an empty array that will hold the names of our mp3 files

    for fname in fnames:  
        if fname.endswith(suffix):
            pname = os.path.abspath(fname)
            #pname = fname
            #print pname

            files.append(pname)  #add the mp3 files to our array
    print files

    for i in files:
        #print i 
        move(i)

def move(fileName):
    call("move /-y "+ fileName +" C:\Music")
    return

if __name__=='__main__':main()

I've looked at the subprocess library and countless other articles, but I still have no clue what I'm doing wrong.

Chris Knadler
  • 2,819
  • 2
  • 26
  • 32
Beawulf
  • 21
  • 1
  • 1
  • 2

3 Answers3

7

The subprocess.call method taks a list of parameters not a string with space separators unless you tell it to use the shell which is not recommended if the string can contain anything from user input.

The best way is to build the command as a list

e.g.

cmd = ["move", "/-y", fileName, "C:\Music"]
call(cmd)

this also makes it easier to pass parameters (e.g. paths or files) with spaces in to the called program.

Both these ways are given in the subprocess documentation.

You can pass in a delimited string but then you have to let the shell process the arguments

call("move /-y "+ fileName +" C:\Music", shell=True)

Also in this case for move there is a python command to do this. shutil.move

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
0

I'm not answering your question directly, but for such tasks, plumbum is great and would make your life so much easier. subprocess's api is not very intuitive.

shx2
  • 61,779
  • 13
  • 130
  • 153
0

There could be several issues:

  1. fileName might contain a space in it so the move command only sees a part of filename.

  2. if move is an internal command; you might need shell=True to run it:

from subprocess import check_call

check_call(r"move /-y C:\Users\Alex\Downloads\*.mp3 C:\Music", shell=True)

To move .mp3 files from Downloads folder to Music without subprocess:

from glob import glob
from shutil import move

for path in glob(r"C:\Users\Alex\Downloads\*.mp3"):
    move(path, r"C:\Music")
jfs
  • 399,953
  • 195
  • 994
  • 1,670