旅游网站建设的方向,惠州手机网站商城建设,跨境电商开发公司,亦庄网站建设价格此贴python源码是linux系统more基本命令的实现。 实现linux中more的基本功能#xff0c;当more后加一个文件名参数时候#xff0c;分屏显示按空格换页#xff0c;按回车换行,在左下角显示百分比#xff1b; 以处理管道参数的输入#xff0c;处理选项num:从指定行开始显示当more后加一个文件名参数时候分屏显示按空格换页按回车换行,在左下角显示百分比 以处理管道参数的输入处理选项num:从指定行开始显示/string :查找字符串从指定字符串之后开始显示
运行环境安装有PYTHON的linux系统
调用示例 more.py [num ] [/pattern] filename command|./more.py [num ] [/pattern] more.p --help 输出帮助信息 num 是 要从第几行开始显示pattern是要在文件中查找的字符串 #!/usr/bin/env python
# -*- coding:utf-8-*-
#文件名字:more.pyimport os
import sys
import curses #用于获取终端的尺寸
import re #用于字符匹配
import signal #用于处理ctrlc中断
import fcntl # 处理显示过程中屏幕的变化
import termios #获取终端信息
import struct
page_len 0 #满屏时可以显示的最大行数
line_len 0 #满屏时每行可以显示的最大字节数
sig_up 0 #中断信号标志
winsz_chg 0 #窗口大小改变标志def win_sz_chg(signum, frame): 函数功能本函数是屏幕变化信号的处理函数global page_len, line_len, winsz_chgwinsz_chg 1signal.signal(signal.SIGWINCH, signal.SIG_IGN)s struct.pack(HHHH, 0, 0, 0, 0) a struct.unpack(hhhh, fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ , s))#获取当前窗口的大小page_len int(a[0]) - 1 #留一行显示进度line_len int(a[1])signal.signal(signal.SIGWINCH, win_sz_chg) #不调用会导致只能检测一次屏幕变化signal.signal(signal.SIGWINCH, win_sz_chg) #接收处理窗口改变信号def term_do_exit(signum, frame): 函数功能键盘中断信号的响应函数global sig_upsig_up 1 #将键盘中断标志置1os.system(stty -F /dev/tty echo) #恢复终端输出回车有效状态os.system(stty -F /dev/tty -cbreak)#重新设着屏幕为输入字符回显状态returnsignal.signal(signal.SIGINT, term_do_exit) #接收并处理键盘中断信号def usage():显示脚本的各参数的含义和调用格式print -----------------usage-----------------print 1./more.py [num] [/pattern] filenameprint 2 command | ./more.pyprint num: Start at line number num. print pattern:Start at line number num.print space: next pageprint q :do_exit the programprint enter:next lineprint----------------------------------------sys.exit()def do_exit():用于系统退出 os.system(stty -F /dev/tty echo) #恢复终端输出回车有效状态os.system(stty -F /dev/tty -cbreak)#重新设着屏幕为输入字符回显状态sys.exit()def is_input(): 检测是否有管道数据输入 try:f sys.stdin.fileno() #判断时候有管道输入init_tty termios.tcgetattr(f) #当没有管道输入也没有参数时候显示提示return 0except:return 1def get_line_num(args): 从命令行参数中获取开始显示的指定行参数args:从命令行获取的参数返回值要开始显示的指定行 line_num 1for i in args: #匹配要从第几行开始的行数ln re.search(r\\d, str(i))if ln:line_num int(ln.group().lstrip())#采用正则表达式处理去掉‘’得到开始显示的行号breakreturn line_numdef get_patstr(args):从命令行中获取要查找的字符串参数args:从命令行中获取的参数为返回值要查找的字符串: patstr for i in args: #获取要匹配的字符串pa re.search(r(\\/\w*[^\s]), str(i))if pa:breakif pa:patstr str(pa.group().lstrip(/))return patstrdef get_args():用于从命令行获取参数解析各参数返回值(line_num,patstr,fp):要开始显示的指定行要查找的字符串要操作的文件对象 line_num 1patstr args sys.argv[1:]if not args:if is_input(): #在没有参数时候判断是否为管道命令输入不是提示正确输入参数fp sys.stdinreturn (line_num, patstr, fp)else:usage()else:if args[-1] --help:usage()line_num get_l
2000
ine_num(args)patstr get_patstr(args)if not in args[-1]:filename args[-1]if not os.path.exists(filename):print 没有那个文件或目录do_exit()else:fp open(filename)else:if not is_input():usage()else:fp sys.stdinreturn (line_num, patstr, fp)def get_screen_size(): 用于获取文件显示终端的尺寸 global page_len, line_len screen curses.initscr() page_len, line_len screen.getmaxyx()#获取屏幕显示尺寸page_len page_len - 2 #去掉输入命令那行和最后要显示more的那一行curses.endwin() #此处不结束会导致后面显示的乱码def show_more(pre_pg_len): 等待键盘输入命令 进行相应的处理。:param pre_pg_len:屏幕改变以前保存的可显示的最大行数global sig_up, winsz_chg, page_lenft open(/dev/tty) #打开标准终端输入sys.stdout.flush() #刷新缓存输出否则显示会出现问题c while True:try:c ft.read(1)#读取一个字符except IOError:if sig_up:do_exit() #键盘中断退出程序if c :print \033[20D\033[K #控制光标回到more--反白字体的行首删除此行以达到more不随文字滚动效果if winsz_chg: #如果此时屏幕大小变化第一次返回之前屏幕满屏行数winsz_chg 0return pre_pg_lenelse:return page_len #当输入是空格时候分屏显示显示下一屏elif c q:print \033[20D\033[Kreturn 0 #当输入是q时退出显示elif c \n:print \033[20D\033[K,return 1 #当输入是换行符时候多显示一行def skip_ln(fp, line_num): 读取文件到指定开始显示的行 n line_num - 1while n:fp.readline()if not fp:returnn n - 1def search(fp, patstr): 在文件中寻找要查找的字符串。:param fp:要显示的文件对象 :param patstr:要查找的检索词 global sig_uptext while True:try:s fp.read(1) if not s:print can not find the string in the filedo_exit()text text sif patstr in text:returnexcept IOError:if sig_up:do_exit()def show_prog(read_size, total_size): 在显示屏幕的左下角显示反显的More当要显示的是一个文件时同时显示已经显示文件的百分比当显示的是一个管道输入时只显示“More”:param read_size: 已经显示的文件:param total_size:要显示的文件的总大小 if total_size:prog int(read_size * 100 / float(total_size))print \033[7m --More-- str(prog) % \033[0m, #输出反白的文字“more”和显示百分数else:print \033[7m --More-- \033[0m, #输出反白的文字“more”returndef do_more(fp , line_num , patstr):分屏显示文件内容:param fp:要显示的文件对象:param page_len: 可显示的最大行数:param line_len:可每行可显示的最大字节数 global page_len, line_lenread_size 0total_size 0os.system(stty -F /dev/tty cbreak) #调用linux命令设置屏幕为不等回车os.system(stty -F /dev/tty -echo )#设置屏幕为输入字符不回显if fp ! sys.stdin:fp.seek(0, 2) #获取文件的总字节数以便后来显示输出的百分比 total_size fp.tell()fp.seek(0, 0)if line_num ! 1:skip_ln(fp, line_num)if patstr:search(fp, patstr)try:line fp.readline(line_len)#按行读取文件可以设置最大读取字数当遇到“\n”时候将\n读入结束。read_size len(line)num_lns 0while line:if num_lns page_len: #每次输出满屏后等待指令pre_pg_len page_lenshow_prog(read_size, total_size)reply show_more(pre_pg_len) if reply 0:breaknum_lns - replyprint line.strip(\n) #用,来消除print 输出的换行符sys.stdout.flush() #刷新缓存否则会出现文件显示迟缓的问题read_size read_size len(line)num_lns 1line fp.readline(line_len)fp.close()except IOError:if sig_up:do_exit()if __name__ __main__:get_screen_size() #获取显示终端的尺寸(line_num, patstr, fp) get_args()do_more(fp, line_num, patstr)do_exit()