Skip to content

Instantly share code, notes, and snippets.

@iRhonin
Created July 20, 2018 12:35
Show Gist options
  • Save iRhonin/b45ce1698fdb572cb74d0b862ebeac48 to your computer and use it in GitHub Desktop.
Save iRhonin/b45ce1698fdb572cb74d0b862ebeac48 to your computer and use it in GitHub Desktop.
Tiny cp command with -r option in python 3.6
#! /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