• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    使用Python腳本在Linux下實現部分BashShell的教程

    來源:懂視網 責編:小采 時間:2020-11-27 14:32:42
    文檔

    使用Python腳本在Linux下實現部分BashShell的教程

    使用Python腳本在Linux下實現部分BashShell的教程:對于Linux用戶來說,命令行的名聲相當的高。不像其他操作系統,命令行是一個可怕的命題,但是對于Linux社區中那些經驗豐富的大牛,命令行卻是最值得推薦鼓勵使用的。通常,命令行對比圖形用戶界面,更能提供更優雅和更高效的解決方案。 命令行伴隨著Linu
    推薦度:
    導讀使用Python腳本在Linux下實現部分BashShell的教程:對于Linux用戶來說,命令行的名聲相當的高。不像其他操作系統,命令行是一個可怕的命題,但是對于Linux社區中那些經驗豐富的大牛,命令行卻是最值得推薦鼓勵使用的。通常,命令行對比圖形用戶界面,更能提供更優雅和更高效的解決方案。 命令行伴隨著Linu

    對于Linux用戶來說,命令行的名聲相當的高。不像其他操作系統,命令行是一個可怕的命題,但是對于Linux社區中那些經驗豐富的大牛,命令行卻是最值得推薦鼓勵使用的。通常,命令行對比圖形用戶界面,更能提供更優雅和更高效的解決方案。

    命令行伴隨著Linux社區的成長,UNIX shells,例如 bash和zsh,已經成長為一個強大的工具,也是UNIX shell的重要組成部分。使用bash和其他類似的shells,可以得到一些很有用的功能,例如,管道,文件名通配符和從文件中讀取命令,也就是腳本。


    讓我們在實際操作中來介紹命令行的強大功能吧。每當用戶登陸某服務后,他們的用戶名都被記錄到一個文本文件。例如,我們來看看有多少獨立用戶曾經使用過該服務。

    以下一系列的命令展現了由一個個小的命令串接起來后所實現的強大功能:

    $ cat names.log | sort | uniq | wc -l
    

    管道符號(|)把一個命令的標準輸出傳送給另外一個命令的標準輸入。在這個例子中,把cat names.log的輸出傳送給sort命令的輸入。sort命令是把每一行按字母順序重新排序。接下來,管道把輸出傳送至uniq命令,它可以刪除重復名字。最后,uniq的輸出又傳送給wc命令。wc是一個字符計數命令,使用-l參數,可以返回行的數量。管道可以讓你把一系列的命令串接在一起。


    但是,有時候需求會很復雜,串接命令會變得十分笨重。在這個情況下,shell腳本可以解決這個問題。shell腳本就是一系列的命令,被shell程序所讀取,并按順序執行。Shell腳本同樣支持一些編程語言的特性,例如變量,流程控制和數據結構。shell腳步對于經常重復運行的批處理程序非常有用。但是,shell腳本也有一些弱點:

  • shell腳本很容易變為復雜的代碼,導致開發人員難于閱讀和修改它們。
  • 通常,它的語法和解釋都不是那么靈活,而且不直觀。
  • 它代碼通常不能被其他腳本使用。腳本中的代碼重用率很低,并且腳本通常是解決一些很具體的問題。
  • 它們一般不支持庫特性,例如HTML解釋器或者處理HTTP請求庫,因為庫一般都只出現在流行的語言和腳本語言中。
  • 這些問題通常會導致腳本變得不靈活,并且浪費開發人員大量的時間。而Python語言作為它的替代品,是相當不錯的選擇。使用python作為shell腳本的替代,通常有很多優勢:

  • python在主流的linux發行版本中都被默認安裝。打開命令行,輸入python就可以立刻進入python的世界。這個特性,讓它可以成為大多腳本任務的最好選擇。
  • python非常容易閱讀,語法容易理解。它的風格注重編寫簡約和干凈的代碼,允許開發人員編寫適合shell腳本的風格代碼。
  • python是一個解釋性語言,這意味著,不需要編譯。這讓python成為最理想的腳本語言。python同時還是讀取,演繹,輸出的循環風格,這允許開發人員可以快速的通過解釋器嘗試新的代碼。開發人員無需重新編寫整個程序,就可以實現自己的一些想法。
  • python是一個功能齊全的編程語言。代碼重用非常簡單,因為python模塊可以在腳本中方便的導入和使用。腳本可以輕易的擴展。
  • python可以訪問優秀的標準庫,還有大量的實現多種功能的第三方庫。例如解釋器和請求庫。例如,python的標準庫包含時間庫,允許我們把時間轉換為我們想要的各種格式,而且可以和其他日期做比較。
  • python可以是命令鏈中的一部分。python不能完全代替bash。python程序可以像UNIX風格那樣(從標準輸入讀取,從標準輸出中輸出),所以python程序可以實現一些shell命令,例如cat和sort。
  • 讓我們基于文章前面提到問題,重新使用python構建。除了已完成的工作,還讓我們來看看某個用戶登陸系統到底有多少次。uniq命令只是簡單的刪除重復記錄,而沒有提示到底這些重復記錄重復了多少次。我們使用python腳本替代uniq命令,而且腳本可以作為命令鏈中的一部分。以下是python程序實現這個功能(在這個例子中,腳本叫做namescount.py):


    #!/usr/bin/env python
    import sys
     
    if __name__ == "__main__":
     # 初始化一個names的字典,內容為空
     # 字典中為name和出現數量的鍵值對
     names = {}
     # sys.stdin是一個文件對象。 所有引用于file對象的方法,
     # 都可以應用于sys.stdin.
     for name in sys.stdin.readlines():
     # 每一行都有一個newline字符做結尾
     # 我們需要刪除它
     name = name.strip()
     if name in names:
     names[name] += 1
     else:
     names[name] = 1
     
     # 迭代字典,
     # 
    輸出名字,空格,接著是該名字出現的數量 for name, count in names.iteritems(): sys.stdout.write("%d %s " % (count, name))

    讓我們來看看python腳本如何在命令鏈中起作用的。首先,它從標準輸入sys.stdin對象讀取數據。所有的輸出都寫到sys.stdout對象里面,這個對象是python里面的標準輸出的實現。然后使用python字典(在其他語言中,叫做哈希表)來保存名字和重復次數的映射。要讀取所有用戶的登陸次數,只需執行下面的命令:

    $ cat names.log | python namescount.py
    


    這里會輸出某用戶出現的次數還有他的名字,使用tab作為分隔符。接下來的事情就是,以用戶登陸次數的降序順序輸出。這可以在python中實現,但是讓我們使用UNIX的命令來實現吧。前面已經提到,使用sort命令可以按字母順序排序。如果sort命令接收一個-rn參數,那么它就會按照數字的降序方式做排序。因為python腳本輸出到標準輸出,所以我們可以使用管道鏈接sort命令,獲取該輸出:

    $ cat names.log | python namescount.py | sort -rn
    

    這個例子使用了python作為命令鏈中的一部分。使用python的優勢是:

  • 可以跟例如cat和sort這樣的命令鏈接在一起。簡單的工具(讀取文件,給文件按數字排序),可以使用成熟的UNIX命令。這些命令都是一行一行的讀取,這意味著這些命令可以兼容大容量的文件,而且它們的效率很高。
  • 如果命令鏈條中某部分很難實現,很清晰,我們可以使用python腳本,這可以讓我們做我們想做的,然后減輕鏈條一下個命令的負擔。
  • python是一個可重用的模塊,雖然這個例子是指定了names,如果你需要處理重復行的其他輸入,你可以輸出每一行,還有該行的重復次數。讓python腳本模塊化,這樣你就可以把它應用到其他地方。
  • 為了演示python腳本中結合模塊和管道風格的強大力量,讓我們擴展一下這個問題。讓我們來找出使用服務最多的前5位用戶。head命令可以讓我們指定需要輸出的行數。在命令鏈中加入這個命令:

    $ cat names.log | python namescount.py | sort -rn | head -n 5
    

    這個命令只會列出前5位用戶。類似的,獲取使用該服務最少的5位用戶,你可以使用tail命令,這個命令使用同樣的參數。python命令的結果輸出到標準輸出,這樣可以允許你擴展和構建它的功能。


    為了演示腳本的模塊化特性,我們又來擴展一下問題。該服務同樣生成一個以逗號分割的csv的日志文件,其中包含,一個email地址列表,還有該地址對我們服務的評價。如下是其中一個例子:

    "email@example.com", "This service is great."
    


    這個任務是,提供一個途徑,來發送一個感謝信息給使用該服務最多的前10位用戶。首先,我們需要一個腳本讀取csv和輸出其中某一個字段。python提供一個標準的csv讀取模塊。以下的python腳本實現了這個功能:

    #!/usr/bin/env python
    # CSV module that comes with the Python standard library
    import csv
    import sys
     
     
    if __name__ == "__main__":
     # CSV模塊使用一個reader對象作為輸入
     # 在這個例子中,就是 sys.stdin.
     csvfile = csv.reader(sys.stdin)
     
     # 這個腳本必須接收一個參數,指定列的序號
     # 使用sys.argv獲取參數.
     column_number = 0
     if len(sys.argv) > 1:
     column_number = int(sys.argv[1])
     
     # CSV文件的每一行都是用逗號作為字段的分隔符
     for row in csvfile:
     print row[column_number]
    

    這個腳本可以把csv轉換并返回參數指定的字段的文本。它使用print代替sys.stout.write,因為print默認使用標準輸出最為它的輸出文件。

    讓我們把這個腳步添加到命令鏈中。新的腳本跟其他命令組合在一起,實現輸出評論最多的email地址。(假設.csv 文件名稱為emailcomments.csv,新的腳本為csvcolumn.py)


    接下來,你需要一個發送郵件的方法,在Python 函數標準庫中,你可以導入smtplib 庫,這是一個用來連接SMTP服務器并發送郵件的模塊。讓我們寫一個簡單的Python腳本,使用這個模塊發送一個郵件給每個top 10 的用戶。

    #!/usr/bin/env python
    import smtplib
    import sys
     
     
    GMAIL_SMTP_SERVER = "smtp.gmail.com"
    GMAIL_SMTP_PORT = 587
     
    GMAIL_EMAIL = "Your Gmail Email Goes Here"
    GMAIL_PASSWORD = "Your Gmail Password Goes Here"
     
     
    def initialize_smtp_server():
     '''
     This function initializes and greets the smtp server.
     It logs in using the provided credentials and returns
     the smtp server object as a result.
     '''
     smtpserver = smtplib.SMTP(GMAIL_SMTP_SERVER, GMAIL_SMTP_PORT)
     smtpserver.ehlo()
     smtpserver.starttls()
     smtpserver.ehlo()
     smtpserver.login(GMAIL_EMAIL, GMAIL_PASSWORD)
     return smtpserver
     
     
    def send_thank_you_mail(email):
     to_email = email
     from_email = GMAIL_EMAIL
     subj = "Thanks for being an active commenter"
     # The header consists of the To and From and Subject lines
     # separated using a newline character
     header = "To:%s
    From:%s
    Subject:%s 
    " % (to_email,
     from_email, subj)
     # Hard-coded templates are not best practice.
     msg_body = """
     Hi %s,
     
     Thank you very much for your repeated comments on our service.
     The interaction is much appreciated.
     
     Thank You.""" % email
     content = header + "
    " + msg_body
     smtpserver = initialize_smtp_server()
     smtpserver.sendmail(from_email, to_email, content)
     smtpserver.close()
     
     
    if __name__ == "__main__":
     # for every line of input.
     for email in sys.stdin.readlines():
     send_thank_you_mail(email)
    

    這個python腳本能夠連接任何的SMTP服務器,不管是在本地還是遠程。為便于使用,我使用了Gmail的SMTP服務器,正常情況下,應該提供你連接Gmail的密碼口令,這個腳本使用了smtp庫中的函數發送郵件。再一次證明使用Python腳本的強大之處,類似SMTP這樣的交互操作使用python來寫的話是比較簡單易讀的。相同的shell腳本的話,可能是比較復雜并且像SMTP這樣的庫是基本沒有的。

    為了發送電子郵件給評論頻率最高的前十名用戶,首先必須單獨得到電子郵件列的內容。要取出某一列,在Linux中你可以使用cut命令。在下面的例子中,命令是在兩個單獨的串。為了便于使用,我寫輸出到一個臨時文件,其中可以加載到第二串命令中。這只是讓過程更具可讀性(Python發送郵件腳本簡稱為sendemail.py):

    $ cat emailcomments.csv | python csvcolumn.py |
     ?python namescount.py | sort -rn > /tmp/comment_freq
    $ cat /tmp/comment_freq | head -n 10 | cut -f2 |
     ?python sendemail.py
    

    這表明Python作為一種實用工具如bash命令鏈的真正威力。編寫的腳本從標準輸入接受 數據并且將任何輸出寫入到標準輸出,允許開發者串起這些命令, 鏈中的這些快速,簡單的命令以及Python程序。這種只為一個目的設計小程序的哲學非常適用于這里所使用的命令流方式。


    通常在命令行中使用的Python腳本,當他們運行某個命令時,參數由用戶來選擇。例如,head命令取得一個-n的參數標志和它后面的數字,然后只打印這個數字大小的行數。Python腳本的每一個參數都是通過sys.argv數組提供,可在import sys后來訪問。下面的代碼顯示了如何使用單個詞語作為參數。此程序是一個簡單的加法器,它有兩個數字參數,將它們相加,并打印輸出給用戶。然而,這種命令行參數使用方式是非常基礎的。這也是很容易出錯誤的 ——例如,輸入兩個字符串,如hello和world,這個命令,你會一開始就得到錯誤:

    #!/usr/bin/env python
    import sys
     
    if __name__ == "__main__":
     # The first argument of sys.argv is always the filename,
     # meaning that the length of system arguments will be
     # more than one, when command-line arguments exist.
     if len(sys.argv) > 2:
     num1 = long(sys.argv[1])
     num2 = long(sys.argv[2])
     else:
     print "This command takes two arguments and adds them"
     print "Less than two arguments given."
     sys.exit(1)
     print "%s" % str(num1 + num2)
    

    慶幸的是,Python有很多處理有關命令行參數的模塊。我個人比較喜歡OptionParser。OptionParser是標準庫提供的optparse模塊的一部分。OptionParser允許你對命令行參數做一系列非常有用的操作。

  • 如果沒有提供具體的參數,可以指定默認的參數
  • 它支持參數標志(顯示或不顯示)和參數值(-n 10000)。
  • 它支持傳遞參數的不同格式——例如,有差別的-n=100000和-n 100000。
  • 我們來用OptionParser來改進sending-mail腳本。原來的腳本有很多的變量硬編碼的地方,比如SMTP細節和用戶的登錄憑據。在下面提供的代碼,在這些變量是用來傳遞命令行參數:

    #!/usr/bin/env python
    import smtplib
    import sys
     
    from optparse import OptionParser
     
    def initialize_smtp_server(smtpserver, smtpport, email, pwd):
     '''
     This function initializes and greets the SMTP server.
     It logs in using the provided credentials and returns the
     SMTP server object as a result.
     '''
     smtpserver = smtplib.SMTP(smtpserver, smtpport)
     smtpserver.ehlo()
     smtpserver.starttls()
     smtpserver.ehlo()
     smtpserver.login(email, pwd)
     return smtpserver
     
     
    def send_thank_you_mail(email, smtpserver):
     to_email = email
     from_email = GMAIL_EMAIL
     subj = "Thanks for being an active commenter"
     # The header consists of the To and From and Subject lines
     # separated using a newline character.
     header = "To:%s
    From:%s
    Subject:%s 
    " % (to_email,
     from_email, subj)
     # Hard-coded templates are not best practice.
     msg_body = """
     Hi %s,
     
     Thank you very much for your repeated comments on our service.
     The interaction is much appreciated.
     
     Thank You.""" % email
     content = header + "
    " + msg_body
     smtpserver.sendmail(from_email, to_email, content)
     
     
    if __name__ == "__main__":
     usage = "usage: %prog [options]"
     parser = OptionParser(usage=usage)
     parser.add_option("--email", dest="email",
     help="email to login to smtp server")
     parser.add_option("--pwd", dest="pwd",
     help="password to login to smtp server")
     parser.add_option("--smtp-server", dest="smtpserver",
     help="smtp server url", default="smtp.gmail.com")
     parser.add_option("--smtp-port", dest="smtpserverport",
     help="smtp server port", default=587)
     options, args = parser.parse_args()
     
     if not (options.email or options.pwd):
     parser.error("Must provide both an email and a password")
     
     smtpserver = initialize_smtp_server(options.stmpserver,
     options.smtpserverport, options.email, options.pwd)
     
     # for every line of input.
     for email in sys.stdin.readlines():
     send_thank_you_mail(email, smtpserver)
     smtpserver.close()
    

    這個腳本顯示OptionParser 的作用。它提供了一個簡單、易于使用的接口給命令行參數, 允許你為每個命令行選項定義某些屬性。它還允許你指定默認值。如果沒有給出某些參數,它可以給你報出特定錯誤。


    現在你學到了多少?并不是使用一個python腳本替代所有的bash命令,我們更推薦讓python完成其中某些困難的任務。這需要更多的模塊化和重用的腳本,還要好好利用python的強大功能。

    使用stdin作為文件對象,這可以允許python讀取輸入,這個輸入是由管道傳輸其他命令的輸出給它的,而把輸出輸出到stout,可以允許python把信息傳遞到管道系統的下一環節。結合這些功能,可以實現強大的程序。在這里提到的例子,就是要實現一個處理服務的日志文件。

    在實際應用中,我最近在處理一個GB級別的CSV文件,我需要使用python腳本轉換一個包含插入數據的SQL命令。了解我需要處理的文件,并在一個表中處理這些數據,腳本需要23個小時來執行并生成20GB的SQL文件。使用文章提到的python編程風格的優勢在于,我們不需要把這個文件讀取到內存中。這意味著整個20GB+的文件可以一行一行的處理。而且我們更清晰的分解每一個步驟(讀取,排序,維護和輸出)為一些邏輯步驟。還有我們得到這些命令的保障,其中這些命令都是UNIX類型的環境的核心工具,它們十分高效和穩定,可以幫助我們構建穩定安全的程序。


    另外一個優點在于,我們不需要硬編碼文件名。這樣可以使得程序更靈活,只需傳遞一個參數。例如,如果腳本在某個文件在20000中斷了,我們不需要重新運行腳本,我們可以使用tail來指定失敗的行數,來讓腳本在這個位置繼續運行。

    python在shell中的應用范圍很廣,不局限于本文所述,例如os模塊和subprocess模塊。os模塊是一個標準庫,可以執行很多操作系統級別的操作,例如列出目錄的結構,文件的統計信息,還有一個優秀的os.path子模塊,可以處理規范目錄路徑。subprocess模塊允許python程序運行系統命令和其他高級命令,例如,上文提到的使用python代碼和spawned進程之間的管道處理。如果你需要編寫python的shell腳本,這些庫都值得去研究的。

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    使用Python腳本在Linux下實現部分BashShell的教程

    使用Python腳本在Linux下實現部分BashShell的教程:對于Linux用戶來說,命令行的名聲相當的高。不像其他操作系統,命令行是一個可怕的命題,但是對于Linux社區中那些經驗豐富的大牛,命令行卻是最值得推薦鼓勵使用的。通常,命令行對比圖形用戶界面,更能提供更優雅和更高效的解決方案。 命令行伴隨著Linu
    推薦度:
    標簽: 使用 腳本 linux
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 亚洲精品视频免费| 久久精品中文字幕久久| heyzo高无码国产精品| 欧美日韩国产精品自在自线| 亚洲嫩草影院久久精品| 久久亚洲私人国产精品vA| 精品久久久久久国产免费了| 国产成人精品日本亚洲专一区 | 国产三级精品三级在线观看| CAOPORM国产精品视频免费| 亚洲精品麻豆av| 久久www免费人成精品香蕉| 午夜精品免费在线观看| 国产精品区一区二区三在线播放 | 午夜精品一区二区三区免费视频| 精品国产亚洲男女在线线电影 | 亚洲国产成人精品不卡青青草原 | 亚洲国产成人精品无码久久久久久综合| 999精品色在线播放| 久久精品国产精品青草app| 97精品一区二区视频在线观看| 久久国产亚洲精品无码| 色妞ww精品视频7777| 亚洲精品国产精品乱码视色| 亚洲综合国产精品第一页| 欧美精品一区二区三区免费| 国产亚洲精品自在线观看| 欧美精品人爱c欧美精品| 成人午夜精品视频在线观看| 国产精品女同一区二区| 精品国产AV一区二区三区| 精品一区二区三区免费毛片爱| 欧洲精品99毛片免费高清观看| 熟妇人妻VA精品中文字幕| 日韩精品中文字幕无码一区| 四虎国产成人永久精品免费| 老司机亚洲精品影院无码| 久久精品国产久精国产思思| 国产精品一区二区久久国产| 国产精品白丝AV网站| 国产在视频线精品视频二代|