Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 1 | # Module 'shutil' -- utility functions usable in a shell-like program |
Guido van Rossum | 277206b | 1997-04-29 13:08:15 +0000 | [diff] [blame^] | 2 | # XXX The copy*() functions here don't copy the data fork on Mac |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 3 | |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 4 | import os |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 5 | |
| 6 | MODEBITS = 010000 # Lower 12 mode bits |
| 7 | # Change this to 01000 (9 mode bits) to avoid copying setuid etc. |
| 8 | |
| 9 | # Copy data from src to dst |
| 10 | # |
| 11 | def copyfile(src, dst): |
Guido van Rossum | 277206b | 1997-04-29 13:08:15 +0000 | [diff] [blame^] | 12 | fsrc = None |
| 13 | fdst = None |
| 14 | try: |
| 15 | fsrc = open(src, 'rb') |
| 16 | fdst = open(dst, 'wb') |
| 17 | while 1: |
| 18 | buf = fsrc.read(16*1024) |
| 19 | if not buf: |
| 20 | break |
| 21 | fdst.write(buf) |
| 22 | finally: |
| 23 | if fdst: |
| 24 | fdst.close() |
| 25 | if fsrc: |
| 26 | fsrc.close() |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 27 | |
| 28 | # Copy mode bits from src to dst |
| 29 | # |
| 30 | def copymode(src, dst): |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 31 | st = os.stat(src) |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 32 | mode = divmod(st[0], MODEBITS)[1] |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 33 | os.chmod(dst, mode) |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 34 | |
| 35 | # Copy all stat info (mode bits, atime and mtime) from src to dst |
| 36 | # |
| 37 | def copystat(src, dst): |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 38 | st = os.stat(src) |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 39 | mode = divmod(st[0], MODEBITS)[1] |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 40 | os.chmod(dst, mode) |
| 41 | os.utime(dst, st[7:9]) |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 42 | |
| 43 | # Copy data and mode bits ("cp src dst") |
| 44 | # |
| 45 | def copy(src, dst): |
| 46 | copyfile(src, dst) |
| 47 | copymode(src, dst) |
| 48 | |
| 49 | # Copy data and all stat info ("cp -p src dst") |
| 50 | # |
| 51 | def copy2(src, dst): |
| 52 | copyfile(src, dst) |
| 53 | copystat(src, dst) |
| 54 | |
| 55 | # Recursively copy a directory tree. |
| 56 | # The destination must not already exist. |
| 57 | # |
| 58 | def copytree(src, dst): |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 59 | names = os.listdir(src) |
| 60 | os.mkdir(dst, 0777) |
| 61 | dot_dotdot = (os.curdir, os.pardir) |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 62 | for name in names: |
| 63 | if name not in dot_dotdot: |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 64 | srcname = os.path.join(src, name) |
| 65 | dstname = os.path.join(dst, name) |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 66 | #print 'Copying', srcname, 'to', dstname |
| 67 | try: |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 68 | #if os.path.islink(srcname): |
| 69 | # linkto = os.readlink(srcname) |
| 70 | # os.symlink(linkto, dstname) |
| 71 | #elif os.path.isdir(srcname): |
| 72 | if os.path.isdir(srcname): |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 73 | copytree(srcname, dstname) |
| 74 | else: |
| 75 | copy2(srcname, dstname) |
| 76 | # XXX What about devices, sockets etc.? |
Guido van Rossum | c96207a | 1992-03-31 18:55:40 +0000 | [diff] [blame] | 77 | except os.error, why: |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 78 | print 'Could not copy', srcname, 'to', dstname, |
| 79 | print '(', why[1], ')' |