#!/usr/bin/env python # This program operates much like dd, but with two important differences: # 1. Many features lacking # 2. seek_bytes= param can specify seek offset in bytes, not block size import os import sys import time def parseNumber(numstr): if numstr.endswith("GB"): return int(numstr[:-2]) * 1000 * 1000 * 1000 if numstr.endswith("MB"): return int(numstr[:-2]) * 1000 * 1000 if numstr.endswith("kB"): return int(numstr[:-2]) * 1000 if numstr.endswith("G"): return int(numstr[:-1]) * 1024 * 1024 * 1024 if numstr.endswith("M"): return int(numstr[:-1]) * 1024 * 1024 if numstr.endswith("K"): return int(numstr[:-1]) * 1024 if numstr.endswith("b"): return int(numstr[:-1]) * 512 if numstr.endswith("w"): return int(numstr[:-1]) * 2 if numstr.endswith("c"): return int(numstr[:-1]) if not numstr.isdigit(): print >> sys.stderr, "Don't know how to parse number", numstr sys.exit(1) return int(numstr) def main(argv): arg_if = "" arg_of = "" arg_bs = 512 arg_seek = -1 arg_seek_bytes = -1 for i in argv: if i.startswith("if="): arg_if=i[3:] elif i.startswith("of="): arg_of=i[3:] elif i.startswith("bs="): arg_bs=parseNumber(i[3:]) elif i.startswith("seek="): arg_seek=int(i[5:]) elif i.startswith("seek_bytes="): arg_seek_bytes=parseNumber(i[11:]) if arg_seek >= 0 and arg_seek_bytes >= 0: print >> sys.stderr, "you can't specify seek= and seek_bytes=" sys.exit(1) seek_bytes = 0 if arg_seek >= 0: seek_bytes = arg_seek * arg_bs elif arg_seek_bytes >= 0: seek_bytes = arg_seek_bytes if_fd = 0 of_fd = 1 if len(arg_if) != 0: print >> sys.stderr, "opening for read", arg_if if_fd = os.open(arg_if, os.O_RDONLY) if len(arg_of) != 0: print >> sys.stderr, "opening for write", arg_of of_fd = os.open(arg_of, os.O_WRONLY | os.O_TRUNC | os.O_CREAT) if arg_seek_bytes > 0: print >> sys.stderr, "seeking to", seek_bytes, "bytes in output file" os.lseek(of_fd, seek_bytes, os.SEEK_SET) bytes_copied = 0 t1 = time.time() buf = os.read(if_fd, arg_bs) while len(buf) > 0: bytes_written = 0 while bytes_written < len(buf): bytes_written += os.write(of_fd, buf[bytes_written:]) bytes_copied += bytes_written buf = os.read(if_fd, arg_bs) os.close(if_fd) os.close(of_fd) t2 = time.time() # print timing info print >> sys.stderr, 'copy %d bytes took %0.3f s' % (bytes_copied, t2 - t1) print >> sys.stderr, 'speed: %0.1f MB/s' % \ ((bytes_copied / 1000000) / (t2 - t1)) if __name__ == '__main__': main(sys.argv)