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