溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么用linux系統(tǒng)more基本命令的實現(xiàn)python源碼

發(fā)布時間:2021-11-20 16:53:08 來源:億速云 閱讀:156 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“怎么用linux系統(tǒng)more基本命令的實現(xiàn)python源碼”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么用linux系統(tǒng)more基本命令的實現(xiàn)python源碼”吧!

實現(xiàn)linux中more的基本功能,當more后加一個文件名參數(shù)時候,分屏顯示按空格換頁,按回車換行',在左下角顯示百分比;
以處理管道參數(shù)的輸入,處理選項+num:從指定行開始顯示,+/string :查找字符串,從指定字符串之后開始顯示

運行環(huán)境:安裝有PYTHON的linux系統(tǒng)

調(diào)用示例:
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`   `#滿屏時可以顯示的最大行數(shù)`
`line_len` `=` `0`   `#滿屏時每行可以顯示的最大字節(jié)數(shù)`
`sig_up` `=` `0`    `#中斷信號標志`
`winsz_chg` `=` `0`   `#窗口大小改變標志`
`def` `win_sz_chg(signum, frame):`
`'''  函數(shù)功能:本函數(shù)是屏幕變化信號的處理函數(shù)'''`
`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)` `#不調(diào)用會導致只能檢測一次屏幕變化`
`signal.signal(signal.SIGWINCH, win_sz_chg)` `#接收處理窗口改變信號`
`def` `term_do_exit(signum, frame):`
`'''  函數(shù)功能:鍵盤中斷信號的響應(yīng)函數(shù)'''`
`global` `sig_up`
`sig_up` `=` `1`           `#將鍵盤中斷標志置1`
`os.system(``"stty -F /dev/tty echo"``)` `#恢復終端輸出回車有效狀態(tài)`
`os.system(``"stty -F /dev/tty -cbreak"``)``#重新設(shè)著屏幕為輸入字符回顯狀態(tài)`
`return`
`signal.signal(signal.SIGINT, term_do_exit)` `#接收并處理鍵盤中斷信號`
`def` `usage():`
`'''顯示腳本的各參數(shù)的含義和調(diào)用格式'''`
`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():`
`'''用于系統(tǒng)退出 '''`
`os.system(``"stty -F /dev/tty echo"``)` `#恢復終端輸出回車有效狀態(tài)`
`os.system(``"stty -F /dev/tty -cbreak"``)``#重新設(shè)著屏幕為輸入字符回顯狀態(tài)`
`sys.exit()`
`def` `is_input():`
`''' 檢測是否有管道數(shù)據(jù)輸入 '''`
`try``:`
`f` `=` `sys.stdin.fileno()` `#判斷時候有管道輸入`
`init_tty` `=` `termios.tcgetattr(f)` `#當沒有管道輸入,也沒有參數(shù)時候,顯示提示`
`return` `0`
`except``:`
`return` `1`
`def` `get_line_num(args):`
`''' 從命令行參數(shù)中獲取開始顯示的指定行`
`參數(shù):args:從命令行獲取的參數(shù)返回值:要開始顯示的指定行  '''`
`line_num` `=` `1`
`for` `i` `in` `args:` `#匹配要從第幾行開始的行數(shù)`
`ln` `=` `re.search(r``'\+\d+'``,` `str``(i))`
`if` `ln:`
`line_num` `=` `int``(ln.group().lstrip(``'+'``))``#采用正則表達式處理去掉‘+’,得到開始顯示的行號`
`break`
`return` `line_num`
`def` `get_patstr(args):`
`'''從命令行中獲取要查找的字符串`
`參數(shù):args:從命令行中獲取的參數(shù)為返回值:要查找的字符串:  '''`
`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():`
`'''用于從命令行獲取參數(shù),解析各參數(shù)`
`返回值:(line_num,patstr,fp):要開始顯示的指定行,要查找的字符串,要操作的文件對象 '''`
`line_num` `=` `1`
`patstr` `=` `""`
`args` `=` `sys.argv[``1``:]`
`if` `not` `args:`
`if` `is_input():` `#在沒有參數(shù)時候,判斷是否為管道命令輸入,不是提示正確輸入?yún)?shù)`
`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()` `#此處不結(jié)束會導致后面顯示的亂碼`
`def` `show_more(pre_pg_len):`
`''' 等待鍵盤輸入命令 ,進行相應(yīng)的處理。`
`:param pre_pg_len:屏幕改變以前保存的可顯示的最大行數(shù)'''`
`global`  `sig_up, winsz_chg, page_len`
`ft` `=` `open``(``'/dev/tty'``)` `#打開標準終端輸入`
`sys.stdout.flush()` `#刷新緩存輸出,否則顯示會出現(xiàn)問題`
`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:` `#如果此時屏幕大小變化,第一次返回之前屏幕滿屏行數(shù)`
`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"`
`當要顯示的是一個文件時,同時顯示已經(jīng)顯示文件的百分比`
`當顯示的是一個管道輸入時,只顯示“More”`
`:param read_size: 已經(jīng)顯示的文件`
`:param total_size:要顯示的文件的總大小  '''`
`if` `total_size:`
`prog` `=` `int``(read_size` `*` `100` `/` `float``(total_size))`
`print`  `"\033[7m --More--"` `+` `str``(prog)` `+` `'%'` `+` `"\033[0m"``,` `#輸出反白的文字“more”和顯示百分數(shù)`
`else``:`
`print`  `"\033[7m --More--"` `+` `"\033[0m"``,` `#輸出反白的文字“more”`
`return`
`def` `do_more(fp , line_num , patstr):`
`'''分屏顯示文件內(nèi)容`
`:param fp:要顯示的文件對象`
`:param page_len: 可顯示的最大行數(shù)`
`:param line_len:可每行可顯示的最大字節(jié)數(shù)   '''`
`global` `page_len, line_len`
`read_size` `=` `0`
`total_size` `=` `0`
`os.system(``"stty -F /dev/tty cbreak"``)` `#調(diào)用linux命令設(shè)置屏幕為不等回車`
`os.system(``"stty -F /dev/tty -echo "``)``#設(shè)置屏幕為輸入字符不回顯`
`if` `fp !``=` `sys.stdin:`
`fp.seek(``0``,` `2``)` `#獲取文件的總字節(jié)數(shù),以便后來顯示輸出的百分比`
`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)``#按行讀取文件,可以設(shè)置最大讀取字數(shù),當遇到“\n”時候,將"\n"讀入結(jié)束。`
`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()` `#刷新緩存,否則會出現(xiàn)文件顯示遲緩的問題`
`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系統(tǒng)more基本命令的實現(xiàn)python源碼”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI