此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:`无锡引产打胎哪家好 http://xmobile.wxbhnk120.com/

  `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()`

分享linux系统more基本命令python源码的更多相关文章

  1. linux使用vi浏览python源码

    一.背景 2018/8/15,这一天要分析一个python项目,因此需要浏览代码,而我使用的是ubuntu 16.04,于是作此文 二.步骤 2.1 获取生成tags文件的脚本 http://svn. ...

  2. Python源码剖析|百度网盘免费下载|Python新手入门|Python新手学习资料

    百度网盘免费下载:Python源码剖析|新手免费领取下载 提取码:g78z 目录  · · · · · · 第0章 Python源码剖析——编译Python0.1 Python总体架构0.2 Pyth ...

  3. VS2013编译python源码

    系统:win10 手头有个python模块,是用C写的,想编译安装就需要让python调用C编译器.直接编译发现使用的是vc9编译,不支持C99标准(两个槽点:为啥VS2008都还不支持C99?手头这 ...

  4. 类似py2exe软件真的能保护python源码吗

    类似py2exe软件真的能保护python源码吗 背景 最近写了个工具用于对项目中C/C++文件的字符串常量进行自动化加密处理,用python写的,工具效果不错,所以打算在公司内部推广.为了防止代码泄 ...

  5. Python源码中的PyCodeObject

    1.Python程序的执行过程 Python解释器(interpreter)在执行任何一个Python程序文件时,首先进行的动作都是先对文件中的Python源代码进行编译,编译的主要结果是产生的一组P ...

  6. 【转】类似py2exe软件真的能保护python源码吗

    类似py2exe软件真的能保护python源码吗 背景 最近写了个工具用于对项目中C/C++文件的字符串常量进行自动化加密处理,用python写的,工具效果不错,所以打算在公司内部推广.为了防止代码泄 ...

  7. Linux下USB suspend/resume源码分析【转】

    转自:http://blog.csdn.net/aaronychen/article/details/3928479 Linux下USB suspend/resume源码分析 Author:aaron ...

  8. ubuntu编译python源码的坑

    在linux平台下编译python时只需要3条命令. 编译步骤 在github或https://www.python.org/downloads/中下载python源码 解压压缩包进路目录执行 1. ...

  9. python源码学习(一)——python的总体架构

    python源码学习(一)——python的总体架构 学习环境: 系统:ubuntu 12.04 STLpython版本:2.7既然要学习python的源码,首先我们要在电脑上安装python并且下载 ...

随机推荐

  1. 剑指offer:丑数

    题目描述: 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 解题 ...

  2. func 传参异步方法

    public async Task<T> AssignAsync<T>(string key, Func<T> acquire) {} var result = a ...

  3. 在Linux下运行引入了外部jar包的java程序

    如图:H.java里引入了commons-io-2.2.jar 代码如下: import org.apache.commons.io.IOUtils; public class H{ public s ...

  4. 003-maven开发Java脚手架archrtype-技术点说明

    一.概述 二.技术点说明 2.1.项目结构 凡auto包或文件件,均会被代码生成器再次生成二修改 1.model层 po:BasePO基础类,统一了数据库的基础字段[数据库必须添加如下,与mybati ...

  5. 安卓 android studio 报错 The specified Android SDK Build Tools version (27.0.3) is ignored, as it is below the minimum supported version (28.0.3) for Android Gradle

    今天将项目迁移到另一台笔记本,进行build出现以下问题,导致build失败 报错截图: 大致意思,目前使用的build工具版本27.0.3不合适.因为当前使用Gradle插件版本是3.2.1,这个版 ...

  6. 一秒解决CentOS下service 功能 不能使用 bash: service: command not found

    首先检查自己是否 使用的是root用户 如果是并且还不能用-----执行以下操作 在centos系统中,如果/sbin目录下没有service这个命令,就会出现 bash: service: comm ...

  7. 导入一个eclipse的java项目到IDEA报Cannot find JDK '1.7' for module 'TEST'

    解决办法: 右键你的项目--------------->OPen module settings 将dependencies里面的module sdk改成你安装的java版本就可以了(比如我电脑 ...

  8. [LeetCode] 60. Permutation Sequence 序列排序

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  9. [LeetCode] 247. Strobogrammatic Number II 对称数II

    A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...

  10. consul多数据中心搭建 【h】

    自建IDC后面简称own.阿里云机房ali.腾讯云机房txown机房:内网10.10.10.0/24,边界节点,10.10.10.100/101.xxx.80.xxxali机房:内网10.10.10. ...