【Python】linux系统more基本命令python源码分享

此python源码是linux系统more基本命令的实现。
实现linux中more的基本功能,当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.py`

`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_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.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` `"\033[20D\033[K"` `#控制光标回到more--反白字体的行首,删除此行以达到more不随文字滚动效果`

`if` `winsz_chg:` `#如果此时屏幕大小变化,第一次返回之前屏幕满屏行数`

`winsz_chg` `=` `0`

`return` `pre_pg_len`

`else``:`

`return` `page_len` `#当输入是空格时候,分屏显示,显示下一屏`

`elif` `c` `=``=` `"q"``:`

`print` `"\033[20D\033[K"`

`return` `0`????????? `#当输入是"q"时,退出显示`

`elif` `c` `=``=` `‘\n‘``:`

`print` `"\033[20D\033[K"``,`

`return` `1`?????????? `#当输入是换行符时候,多显示一行`

`def` `skip_ln(fp, line_num):`

`‘‘‘ 读取文件到指定开始显示的行? ‘‘‘`

`n` `=` `line_num` `-` `1`

`while` `n:`

`fp.readline()`

`if` `not` `fp:`

`return`

`n` `=` `n` `-` `1`

`def` `search(fp, patstr):`

`‘‘‘ 在文件中寻找要查找的字符串。`

`:param fp:要显示的文件对象???`

`:param patstr:要查找的检索词? ‘‘‘`

`global`? `sig_up`

`text` `=` `‘ ‘`

`while` `True``:`

`try``:`

`s` `=` `fp.read(``1``)????????`

`if` `not` `s:`

`print` `"can not find the string in the file"`

`do_exit()`

`text` `=` `text` `+` `s`

`if` `patstr` `in` `text:`

`return`

`except` `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”`

`return`

`def` `do_more(fp , line_num , patstr):`

`‘‘‘分屏显示文件内容`

`:param fp:要显示的文件对象`

`:param page_len: 可显示的最大行数`

`:param line_len:可每行可显示的最大字节数?? ‘‘‘`

`global` `page_len, line_len`

`read_size` `=` `0`

`total_size` `=` `0`

`os.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` `=` `0`

`while` `line:`

`if` `num_lns` `=``=` `page_len:` `#每次输出满屏后,等待指令`

`pre_pg_len` `=` `page_len`

`show_prog(read_size, total_size)`

`reply` `=` `show_more(pre_pg_len)??????????`

`if` `reply` `=``=` `0``:`

`break`

`num_lns` `-``=` `reply`

`print` `line.strip(``‘\n‘``)` `#用,来消除print 输出的换行符`

`sys.stdout.flush()` `#刷新缓存,否则会出现文件显示迟缓的问题`

`read_size` `=` `read_size` `+` `len``(line)`

`num_lns` `+``=` `1`

`line` `=` `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()`
Python资源分享qun:855408893  内有安装包,学习视频资料,免费直播实战案例。这里是Python学习者的聚集地,零基础,进阶,都欢迎

原文地址:https://blog.51cto.com/14429370/2416656

时间: 2024-08-04 22:18:56

【Python】linux系统more基本命令python源码分享的相关文章

linux系统下安装Python环境

如何在Linux系统下搭建Python开发环境(http://www.maiziedu.com/course/python/)?Python在Linux系统中安装方法在Windows下是有很大的区别的,今天就具体记录一下关于 Python 环境软件包在Linux系统下的一些安装步骤 1.升级 Python 到 2.7.10( 默认 2.6.6 ) shell > yum -y install epel-release shell > yum -y install gcc wget readli

在linux系统上安装python,django,xftp

在Linux系统上安装python,django,xftp安装Python3.5.6详细文档!!!! 1.安装相关依赖库(工具包) yum install gcc patch libffi-devel python-devel zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel -y 2

karloop介绍--hello world大家好,今天为大家介绍一款非常轻量级的的web开发框架,karloop框架。使用python开发 首先我们下载karloop源码进行安装。 源码地址 下载成

大家好,今天为大家介绍一款非常轻量级的的web开发框架,karloop框架.使用python开发 首先我们下载karloop源码进行安装. 源码地址 下载成功后解压,进入解压后的路径,进入终端,运行命令:sudo python setup.py install 如果是window系统,则打开cmd,运行:python setup.py install 下载安装成功后,我们写一个hello.py 内容如下: # coding=utf-8 from karloop.KarlBaseApplicati

Python Django框架实现商城项目源码加设计文档和注释

Python Django框架实现商城项目源码加设计文档和注释 链接:https://pan.baidu.com/s/1yN2iBgx3zmpTkoY8u1LWRg 提取码:lfsx 非常完整的django项目源码,分享给撸友们,不管是学习还是深造,都是可以学习借鉴的!! 原文地址:https://www.cnblogs.com/zyxlovesjy/p/12115491.html

Linux tcp被动打开内核源码分析

[我是从2个角度来看,其实所谓2个角度,是发现我分析源码时,分析重复了,写了2个分析报告,所以现在都贴出来.] [如果你是想看看,了解一下内核tcp被动打开时如何实现的话,我觉得还是看看概念就可以了,因为即使看了源码,过一个个礼拜你就忘了,如果是你正在修改协议栈,为不知道流程而发愁,那么希望你能看看源码以及注释,希望你给你帮助.] 概念: tcp被动打开,前提是你listen,这个被动打开的前提.你listen过后,其实创建了一个监听套接字,专门负责监听,不会负责传输数据. 当第一个syn包到达

Linux下Zabbix_Server的安装-源码安装

Centos下Zabbix_Server/agent/proxy的安装配置 --------源码编译 完整版请查看附件 一.环境说明 a)软件环境 由于是源码安装,官方的zabbix源码包内已经包含了Server,Proxy, Agent, GUI所有组件和必要的执行脚本,截至本文正式版本限于2.2.3: LAMP环境 n操作系统使用Centos6.5 X86_64 最小化安装,并yum update到最新状态,内核版本为2.6.32-431.17.1.el6.x86_64: nMysql 使用

linux软件包的安装之----源码编译安装

前提:必须装好前面说过的开发环境,rhel6上的3个开发包组 Rhel5/centos5上面安装: 1)Development Tools (2)Server Platform Development (3)Develogmentlibraries Rhel6/centos6上面安装: 1)  Development Tools (2)Server Platform Development (3)Desktop PlatformDevelopment **由于tarball中的c程序源码文件之间

Linux系统下基本命令

<Linux系统下基本命令> Linux系统下基本命令: 要区分大小写 uname 显示版本信息(同win2K的 ver) dir 显示当前目录文件,ls -al 显示包括隐藏文件(同win2K的 dir) pwd 查询当前所在的目录位置 cd cd ..回到上一层目录,注意cd 与..之间有空格.cd /返回到根目录. cat 文件名 查看文件内容 cat >abc.txt 往abc.txt文件中写上内容. more 文件名 以一页一页的方式显示一个文本文件. cp 复制文件 mv 移

linux下MySQL 5.6源码安装

linux下MySQL 5.6源码安装 1.下载:当前mysql版本到了5.6.20 http://dev.mysql.com/downloads/mysql 选择Source Code 2.必要软件包 yum -y install gcc gcc-c++ gcc-g77 autoconf automake zlib* fiex* libxml* ncurses-devel libmcrypt* libtool-ltdl-devel* make cmake 3.编译安装 添加用户 groupad