Skip to content
Advertisement

Getting rid of the apostrophe in subprocess.Popen to move files

My script generates multiple files that contain random names based on the info it extracts. I created this test to try and move all new files created while running into a new directory named after the file being ran.

When I use os.popen("mv " + moveFiles +' ' + filename + "_dir") it works just fine, but os.popen is considered insecure due to shellshock

When switching to cmd = Popen(["mv", str(moveFiles), filename + "_dir"]), I get the following error

mv: cannot stat ‘/home/test/testing/TestFile1.txt /home/test/testing/TestFile2.txt’: No such file or directory

I believe this is due to it adding the apostrophe at the beginning and end of the moveFiles variable which tries to move it as 1 file rather than 2. So it works when a single file is created, but anymore results in the error. Is there a way to remove this?

'/home/test/testing/TestFile1.txt /home/test/testing/TestFile2.txt'
def createDir(filename):
    """
    createDir creates the folder of the file/argument given (Example.txt_dir)
    """
    Dir = str(filename) + "_dir"
    cmd = Popen(["mkdir", Dir], stdout=PIPE, stderr=PIPE) 

def createFiles(filename):
    """
    createFiles creates test files to move into Example.txt_dir
    """
    with open('TestFile1.txt', 'w') as m:
        cmd = Popen(["file", filename], stdout=m, stderr=PIPE)
    print('Saved as TestFile1.txt')

    with open('TestFile2.txt', 'w') as m:
        cmd = Popen(["file", filename], stdout=m, stderr=PIPE)
    print('Saved as TestFile2.txt')

def dirDifference(dir1, dir2):
    """
    dirDifference compares 2 paths, 1 before being ran and 1 after to get a list of all new files to be moved
    """
    #Compares Directory before and after running
    dif = [i for i in dir1 + dir2 if i not in dir1 or i not in dir2]
    separator =  ' '
    x = separator.join(map(str, dif)) 
    return x

def moveDir(filename, moveFiles):
    """
    moveDir: Moves the new files to the directory.
    """
    Dir = str(filename) + "_dir"
    cmd = Popen(["mv", moveFiles, filename + "_dir"])

Advertisement

Answer

Your suspicion is correct: the problem is that you have two filenames joined together with a space. Since you’re using Popen() and not os.popen() you’re bypassing shell interpretation of the arguments, which means that individual filenames aren’t getting separated. This is the same as if you had used quotes on the command line:

mv 'file1 file2' destination
mv: cannot stat 'file1 file2': No such file or directory

You’ve asked it to move a single file whose name has a space in the middle. What you need to do is make each filename a separate element in the list in Popen():

cmd = Popen(["mv", file1, file2, destination])

In the case of your code above, instead of dirDifference() returning filenames joined together with spaces, it could simply return a list, which you could use with Popen():

cmd = Popen(["mv"] + moveFiles + [filename + "_dir"])

(making sure that moveFiles is a non-empty list of course)

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement