分享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:`无锡引产打胎哪家好 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源码的更多相关文章
- linux使用vi浏览python源码
一.背景 2018/8/15,这一天要分析一个python项目,因此需要浏览代码,而我使用的是ubuntu 16.04,于是作此文 二.步骤 2.1 获取生成tags文件的脚本 http://svn. ...
- Python源码剖析|百度网盘免费下载|Python新手入门|Python新手学习资料
百度网盘免费下载:Python源码剖析|新手免费领取下载 提取码:g78z 目录 · · · · · · 第0章 Python源码剖析——编译Python0.1 Python总体架构0.2 Pyth ...
- VS2013编译python源码
系统:win10 手头有个python模块,是用C写的,想编译安装就需要让python调用C编译器.直接编译发现使用的是vc9编译,不支持C99标准(两个槽点:为啥VS2008都还不支持C99?手头这 ...
- 类似py2exe软件真的能保护python源码吗
类似py2exe软件真的能保护python源码吗 背景 最近写了个工具用于对项目中C/C++文件的字符串常量进行自动化加密处理,用python写的,工具效果不错,所以打算在公司内部推广.为了防止代码泄 ...
- Python源码中的PyCodeObject
1.Python程序的执行过程 Python解释器(interpreter)在执行任何一个Python程序文件时,首先进行的动作都是先对文件中的Python源代码进行编译,编译的主要结果是产生的一组P ...
- 【转】类似py2exe软件真的能保护python源码吗
类似py2exe软件真的能保护python源码吗 背景 最近写了个工具用于对项目中C/C++文件的字符串常量进行自动化加密处理,用python写的,工具效果不错,所以打算在公司内部推广.为了防止代码泄 ...
- Linux下USB suspend/resume源码分析【转】
转自:http://blog.csdn.net/aaronychen/article/details/3928479 Linux下USB suspend/resume源码分析 Author:aaron ...
- ubuntu编译python源码的坑
在linux平台下编译python时只需要3条命令. 编译步骤 在github或https://www.python.org/downloads/中下载python源码 解压压缩包进路目录执行 1. ...
- python源码学习(一)——python的总体架构
python源码学习(一)——python的总体架构 学习环境: 系统:ubuntu 12.04 STLpython版本:2.7既然要学习python的源码,首先我们要在电脑上安装python并且下载 ...
随机推荐
- 基于 Mathematica 的机器人仿真环境(机械臂篇)[转]
完美的教程,没有之一,收藏学习. 目的 本文手把手教你在 Mathematica 软件中搭建机器人的仿真环境,具体包括以下内容(所使用的版本是 Mathematica 11.1,更早的版本可能缺少某些 ...
- Android中Activity的启动模式(LaunchMode)和使用场景
一.为什么需要启动模式在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中.当我们点击返回(back)键,这些Ac ...
- 如何解决“HttpException (0x80004005): 超过了最大请求长度”问题
.net mvc项目在做上传文件时,出现这个问题,上传文件的是通过表单提交,后台是通过请求里面获取文件信息的 1.问题截图: 堆栈信息 “/”应用程序中的服务器错误.超过了最大请求长度.说明: 执行当 ...
- 本机安装了oracle,本机还需要安装客户端吗?
转: 本机安装了oracle,本机还需要安装客户端吗? 2017-09-21 15:56:29 Ideality_hunter 阅读数 4681 版权声明:本文为博主原创文章,遵循CC 4.0 B ...
- Java 使用ZkClient操作Zookeeper
目录 ZkClient介绍 导入jar包依赖 简单使用样例 ZkClient介绍 因为Zookeeper API比较复杂,使用并不方便,所以出现了ZkClient,ZkClient对Zookeeper ...
- matlab学习笔记10_7数值计算类型和常用计算公式
一起来学matlab-matlab学习笔记11 数值数据类型以及特殊函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用>张德丰等著 ...
- depth wise CNN
depth wise cnn相对于传统的CNN,区别在于:它是逐通道做卷积操作! 例子如下: (1)使用传统卷积,输入:H*W*C_in,最终输出h*w*C_out:卷积核尺寸为K*K*C_in*C_ ...
- [LeetCode] 451. Sort Characters By Frequency 根据字符出现频率排序
Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: ...
- Spring boot后台搭建二集成Shiro权限控制
上一篇文章,实现了用户验证 查看,接下来实现下权限控制 权限控制,是管理资源访问的过程,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等 Apache Shir ...
- Android MVP框架实现登录案例
一.Model package com.czhappy.mvpdemo.model; /** * author: chenzheng * created on: 2019/5/16 11:06 * d ...