基于argparser模块实现 ls 功能(基本实现)
第一版:实现基本功能,但是没有获取属主,属组,只能在一个目录下,不能传入多个目录:如 ls /etc /tmp
1 import argparse 2 from pathlib import Path 3 import stat # 获取文件权限 mode = stat.filemode(st.st_mode) 4 import datetime 5 6 def iteradir(p:str, all=False, detail=True, human=False): 7 def _gethuman(size:int): 8 unit = ['','M','G','T','P'] # 用字符串好点,序列化时候,节省空间 9 index = 0 10 while size > 1000: # 4001 11 size //= 1000 12 index += 1 13 return '{}{}'.format(size, unit[index]) 14 15 16 def listdir(p:str, all=False, detail=True, human=False): # drwxrwxr-x. 5 py py 4096 Aug 31 18:10 projects 17 path = Path(p) 18 for x in path.iterdir(): 19 if not all and x.name.startswith('.'): 20 continue 21 if detail: 22 st = path.stat() 23 24 mode = stat.filemode(st.st_mode) 25 human = _gethuman(st.st_size) if human else str(st.st_size) # 是否-h 26 atime = datetime.datetime.fromtimestamp(st.st_atime).strftime('%Y/%m/%d %H-%M-%S') 27 yield (mode, st.st_nlink, st.st_uid, st.st_gid, human, atime, x.name) 28 else: 29 yield (x.name,) 30 #返回什么 31 # listdir(p, all, detail, human) 32 #排序 33 yield from sorted(listdir(p, all, detail, human),key=lambda x: x[-1]) 34 35 if __name__ == '__main__': 36 parser = argparse.ArgumentParser( 37 prog = 'ls', 38 description='Process some int', 39 add_help = False 40 ) 41 parser.add_argument('path',nargs='?', default='.', help='file path')# 位置参数 42 parser.add_argument('-l',dest='list', action='store_true') 43 parser.add_argument('-a', '--all', action='store_true') 44 parser.add_argument('-h', '--human-readable', dest='human', action='store_true', help='with -l human size') 45 46 args = parser.parse_args() # 解析:如:/etc ---> e t c 把其当作一个可迭代对象了,所以可以这样输入 ('/etc',) 47 48 49 for i in iteradir(args.path, args.all, args.list, args.human): 50 for j in i: 51 print(j, end='\t') 52 print()
第二版:
基于第一版的修改是:
获取文件的属主,属组,而不是uid,gid
可以多个路径:多个路径返回的path.args 是列表,所以迭代送进去就行!
在linux下,pwd模块,grp模块:
pwd.getpwuid(Path().stat().st_uid).pw_name
grp.getgrgid(Path().stat().st_gid).gr_name
1 import argparse 2 from pathlib import Path 3 import stat 4 import datetime 5 import pwd 6 import grp 7 8 def _human(size:int): 9 unit = [' ', 'k', 'M', 'G', 'T'] 10 count = 0 11 while size > 1000: 12 size /= 1000 13 count += 1 14 return '{}{}'.format(size, unit[count]) 15 16 def lsdir(path:str, all=False, list=False, human=False): 17 p = Path(path) 18 if p.is_dir(): 19 for files in p.iterdir(): 20 if list: 21 if not all and files.name.startswith('.'): 22 continue 23 else: 24 st = files.stat() 25 mode = stat.filemode(st.st_mode) 26 user = pwd.getpwuid(st.st_uid).pw_name 27 atime = datetime.datetime.fromtimestamp(st.st_atime).strftime('%Y/%m/%d:%H:%M:%S') 28 group = grp.getgrgid(st.st_gid).gr_name 29 size = _human(st.st_size) if human else st.st_size 30 print(mode, st.st_nlink, user, group, size, atime, files.name, sep='\t') 31 else: 32 print(files.name, end='\t') 33 print() 34 else: 35 if list: 36 st = p.stat() 37 mode = stat.filemode(st.st_mode) 38 user = pwd.getpwuid(st.st_uid).pw_name 39 group =grp.getgrgid(st.st_gid).gr_name 40 atime = datetime.datetime.fromtimestamp(st.st_atime).strftime('%Y/%m/%d:%H:%M:%S') 41 size = _human(st.st_size) if human else st.st_size 42 print(mode, st.st_nlink, user, group, size, atime, p.name, sep='\t') 43 else: 44 print(p.name, end='\t') 45 print() 46 47 # if __name__ == '__main__': 48 parser = argparse.ArgumentParser( 49 prog = 'ls', 50 description='Process some int', 51 add_help = False 52 ) 53 parser.add_argument('path',nargs='*', default='.', help='file path')# 位置参数 54 parser.add_argument('-l',dest='list', action='store_true') 55 parser.add_argument('-a', '--all', action='store_true') 56 parser.add_argument('-h', '--human-readable', dest='human', action='store_true', help='with -l human size') 57 58 args = parser.parse_args() # 解析:如:/etc ---> e t c 把其当作一个可迭代对象了,所以可以这样输入 ('/etc',) 59 60 61 for i in args.path: 62 print(i, '---------------------------------------') 63 lsdir(i, args.all, args.list, args.human)
为什么要坚持,想一想当初!