并把上面脚本加到环境变量里
chmod 755 more.py ln -n more.py /usr/bin/more1
调用 more1 即可
cat /var/log/dmesg | more1
截图
#!/usr/bin/env python
# -*- coding:utf-8-*-
#名字:more.py
#功能:
# 实现linux中more的基本功能,当more 后加一个文件名参数时候,分屏显示,按空格换页,按回车换行',在左下角显示百分比;
# 可以处理管道参数的输入,处理选项+num:从指定行开始显示,+/string :查找字符串,从指定字符串之后开始显示
#运行环境:
# 安装有PYTHON的linux系统
#调用示例:
# more.py [+num ] [+/pattern] filename
# command|./more.py [+num ] [+/pattern]
# more.p --help 输出帮助信息
# num 是 要从第几行开始显示,pattern是要在文件中查找的字符串
import os
import sys
import curses #用于获取终端的尺寸
import re #用于字符匹配
import signal #用于处理ctrl+c中断
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_chg
winsz_chg = 1
signal.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_up
sig_up = 1 #将键盘中断标志置1
os.system("stty -F /dev/tty echo") #恢复终端输出回车有效状态
os.system("stty -F /dev/tty -cbreak")#重新设着屏幕为输入字符回显状态
return
signal.signal(signal.SIGINT, term_do_exit) #接收并处理键盘中断信号
def usage():
'''显示脚本的各参数的含义和调用格式'''
print "-----------------usage-----------------"
print "1./more.py [+num] [+/pattern] filename"
print "2 command | ./more.py"
print "num: Start at line number num. "
print "pattern:Start at line number num."
print "space: next page"
print "q :do_exit the program"
print "enter:next line"
print"----------------------------------------"
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 0
except:
return 1
def get_line_num(args):
''' 从命令行参数中获取开始显示的指定行
参数:args:从命令行获取的参数返回值:要开始显示的指定行 '''
line_num = 1
for i in args: #匹配要从第几行开始的行数
ln = re.search(r'+d+', str(i))
if ln:
line_num = int(ln.group().lstrip('+'))#采用正则表达式处理去掉‘+’,得到开始显示的行号
break
return line_num
def get_patstr(args):
'''从命令行中获取要查找的字符串
参数:args:从命令行中获取的参数为返回值:要查找的字符串: '''
patstr = ""
for i in args: #获取要匹配的字符串
pa = re.search(r'(+/w*[^s])', str(i))
if pa:
break
if pa:
patstr = str(pa.group().lstrip('+/'))
return patstr
def get_args():
'''用于从命令行获取参数,解析各参数
返回值:(line_num,patstr,fp):要开始显示的指定行,要查找的字符串,要操作的文件对象 '''
line_num = 1
patstr = ""
args = sys.argv[1:]
if not args:
if is_input(): #在没有参数时候,判断是否为管道命令输入,不是提示正确输入参数
fp = sys.stdin
return (line_num, patstr, fp)
else:
usage()
else:
if args[-1] == "--help":
usage()
line_num = get_line_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.stdin
return (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_len
ft = open('/dev/tty') #打开标准终端输入
sys.stdout.flush() #刷新缓存输出,否则显示会出现问题
c = ''
while True:
try:
c = ft.read(1)#读取一个字符
except IOError:
if sig_up:
do_exit() #键盘中断退出程序
if c == " ":
print "