python 模拟linux的 ls 命令
sample: python custom_ls.py -alh c:/
选项:
-a ,--all 显示所有文件,包括'.'开头的隐藏文件
-l 列表显示每个文件详细信息
-h 以人类可读的方式显示,文件大小会被换算成 K、M、G、T 或 P 的单位
path
只能接受一个path路径,需要改进。
from pathlib import Path import argparse import datetime import stat import os def convert_mode(mode: int): modelist = ['r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x'] m = mode & 0o777 modestr = bin(m)[-9:] ret = "" for i, v in enumerate(modestr): if v == '1': ret += modelist[i] else: ret += '-' return ret def convert_type(file: Path): ret = "" if file.is_symlink(): ret = 'l' elif file.is_fifo(): ret = 'p' elif file.is_socket(): ret = 's' elif file.is_block_device(): ret = 'b' elif file.is_char_device(): ret = 'c' elif file.is_dir(): ret = 'd' elif file.is_file(): ret = '-' else: ret = '?' return ret def list_dir(path: str = '.', all=False, detail=False, human=False): units = ['', 'K', 'M', 'G', 'T', 'P'] def _convert_human(size: int): depth = 0 while size >= 1024: size = size // 1024 depth += 1 return "{}{}".format(size, units[depth]) def _show_dir(path: str = '.', all=False, detail=False, human=False): p = Path(path) for file in p.iterdir(): if not all and str(file.name).startswith('.'): continue if detail: st = file.stat() h = st.st_size if human: h = _convert_human(st.st_size) owner, group = st.st_uid, st.st_gid if os.name == "posix": owner, group = file.owner(), file.group() yield str((stat.filemode(st.st_mode), st.st_nlink, owner, group, str(h), datetime.datetime.fromtimestamp(st.st_atime).strftime('%Y-%m-%d %H:%M:%S'), file.name)).strip( '()') else: yield str((file.name,)).strip('()') yield from sorted(_show_dir(args.path, args.all, args.l, args.h), key=lambda x: x[-1]) parser = argparse.ArgumentParser(prog='ls', add_help=False, description='list directory contents. --20171031') parser.add_argument('path', nargs='?', default='.', help='give a path (files or direction)') parser.add_argument('-l', action='store_true', help='List Display details') parser.add_argument('-h', action='store_true', help='Human readable way to show "kmgtp" size') parser.add_argument('-a', '--all', action='store_true', help='Show hidden files at the same time') if __name__ == '__main__': args = parser.parse_args(('.', '-ahl')) parser.print_help() print('args=', args) for st in list_dir(args.path, args.all, args.l, args.h): print(st)