Take the 2-minute tour ×

I have this function trying to print additional '.' every second while it's copying a big folder (~3GB) from one place to another:

def copy_folder(source, destination):
    print 'copying',
    while shutil.copytree(src=source, dst=destination):
        print '.',

but when I call the function:

source = 'source_folder'
destination = 'destination_folder'
copy_folder(source=source, destination=destination)

it's copying perfectly fine the whole folder but it does NOT print '.' at all.

Do I need to use threads?

share|improve this question
Yes. you need to launch a separate thread to print the periods. See Brianestey's answer. –  Joel Cornett Aug 21 '12 at 2:31
I believe you are mistaken by the semantics of while statement in Python. Here is a good resource: tutorialspoint.com/python/python_while_loop.htm –  behnam Aug 21 '12 at 2:40

4 Answers 4

up vote 4 down vote accepted

Threading in Python is pretty simple:

import sys, shutil, time, threading

class CopyThread(threading.Thread):
    def __init__(self, source, destination):
        super(CopyThread, self).__init__()

        self.source = source
        self.destination = destination

    def run(self):
        time.sleep(5)  # Delete me later on, I'm just here to slow things down
        return shutil.copytree(src=self.source, dst=self.destination)

if __name__ == '__main__':
    thread = CopyThread('source_folder', 'destination_folder')

    while thread.is_alive():



Just subclass threading.Thread and override run(). After that, call .start() on an instance of that class and you have a thread.

share|improve this answer
+1 for is_alive() (no need for a separate variable), and write()+flush(). –  EOL Aug 21 '12 at 3:08
Awesome, thanks very much! –  mawueth Aug 21 '12 at 19:42

copytree will copy the entire tree so the while loop won't run until the copy is complete and the return value can be evaluated.

My python is rusty, but I'll give an idea of how to implement the thread (inspired by the code found here).

def copy_folder(source, destination):
    self.iscopying = True        
    self.thread = threading.Thread(name="GPS Data", target=self.thread_run)
    shutil.copytree(src=source, dst=destination)
    self.iscopying = false

def thread_run(self):
    while self.iscopying:
        print '.'

Essentially, create a flag that tells the thread when the copying is happening and then set it to false when the copy is complete.

share|improve this answer

Looking at the copytree source code, the core of it is this loop:

for name in names:
   if name in ignored_names:
   srcname = os.path.join(src, name)
   dstname = os.path.join(dst, name)
       if symlinks and os.path.islink(srcname):
           linkto = os.readlink(srcname)
           os.symlink(linkto, dstname)
       elif os.path.isdir(srcname):
           copytree(srcname, dstname, symlinks, ignore)
           # Will raise a SpecialFileError for unsupported file types
           copy2(srcname, dstname)
   # catch the Error from the recursive copytree so that we can
   # continue with other files
   except Error, err:
   except EnvironmentError, why:

If you add a yield right at the end, your loop will work - but you would be printing after every file or directory copied, rather than at time intervals (your time.sleep would happen between copies, and just make the whole thing take a bit longer; for every time interval, yes you will need threads). But, this would also allow you to give more detailed feedback if you were so inclined - eg, you could yield name (or, yield (srcname, destname)) to be able to print feedback on which file has been copied.

share|improve this answer
+1 to make your rep not exactly 5,000. This would be pretty useful for a detailed progress bar, so thanks for the tip! –  Blender Aug 21 '12 at 2:49

I don't know of a module to do this asynchronously... Not that there isn't one... But you could recursively go through the folder and print the "." After each file/folder

share|improve this answer

Your Answer


