Created
July 20, 2018 12:35
-
-
Save iRhonin/b45ce1698fdb572cb74d0b862ebeac48 to your computer and use it in GitHub Desktop.
Tiny cp command with -r option in python 3.6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/local/bin/python3.7 | |
import sys | |
import argparse | |
from pathlib import Path | |
from os import path, makedirs | |
def read_file(file_path, chunksize=8192): | |
with open(file_path, mode='rb') as f: | |
while True: | |
chunk = f.read(chunksize) | |
if chunk: | |
yield chunk | |
else: | |
break | |
def copy_file(src_file_path, dst_file_path, is_recursive=False): | |
if path.isdir(src_file_path): | |
print( | |
src_file_path, | |
'is a directory!\nUse --recursive for directories' | |
) | |
return | |
src_dir_path, src_file_name = path.split(src_file_path) | |
dst_dir_path, dst_file_name = path.split(dst_file_path) | |
if dst_file_name is None or path.isdir(dst_file_name): | |
dst_file_name = src_file_name | |
dst_file_path = path.join(dst_dir_path, dst_file_name) | |
try: | |
if is_recursive: | |
makedirs(path.dirname(dst_file_path), exist_ok=True) | |
f = open(dst_file_path, mode='wb') | |
except (FileNoFoundError, PermissionError) as ex: | |
print(ex) | |
exit(-1) | |
try: | |
for chunk in read_file(src_file_path): | |
f.write(chunk) | |
except OSError as ex: | |
print(ex) | |
finally: | |
f.close() | |
return | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument('SOURCE') | |
parser.add_argument('DEST') | |
parser.add_argument( | |
'-r', | |
'--recursive', | |
help='copy directories recursively', | |
action='store_true', | |
) | |
args = parser.parse_args() | |
src_path = path.abspath(args.SOURCE) | |
dst_path = path.abspath(args.DEST) | |
if src_path in dst_path: | |
print(f"cp: cannot copy a directory, " | |
f"'{src_path}', into itself, " | |
f"'{dst_path}'") | |
exit(-1) | |
if not args.recursive: | |
copy_file(src_path, dst_path) | |
exit(0) | |
for file in Path(src_path).glob('**/*'): | |
src_dir_path, src_file_name = path.split(file) | |
dst_path = path.join( | |
args.DEST, | |
path.relpath(src_dir_path, args.SOURCE), | |
src_file_name | |
) | |
if path.isdir(file): | |
continue | |
copy_file(file, dst_path, True) | |
exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment