1. 程式人生 > 程式設計 >Python和Bash結合在一起的方法

Python和Bash結合在一起的方法

對於Linux使用者而言,命令列操作我們已經非常熟悉了。與其他流行的作業系統不同,在Linux社群中,使用命令列與使用圖形使用者介面執行類似任務相比,命令列通常可以提供更優雅,更有效的解決方案。

隨著Linux社群對命令列的依賴不斷增長,UNIX shell(如bash和zsh)已發展成為極其強大的工具,可以補充UNIX shell的經驗。使用bash和其他類似的shell,可以使用許多強大的功能,例如管道,檔名萬用字元以及從稱為指令碼的檔案中讀取命令的功能。

讓我們看一個真實的示例來演示命令列的功能。每次使用者登入服務時,其使用者名稱都會記錄到一個文字檔案中。對於此示例,讓我們找出有多少唯一使用者使用該服務。

以下示例中的一系列命令通過將較小的構建塊連結在一起,顯示了更復雜的實用工具的功能:

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

管道符號(|)用於將一個命令的標準輸出傳遞到下一命令的標準輸入。在此處的示例中,cat names.txt的輸出傳遞到sort命令中。sort命令的輸出是按字母順序重新排列檔案的每一行。隨後將其傳遞給uniq命令,該命令將刪除所有重複的名稱。最後,uniq的輸出傳遞到wc命令。wc是計數命令,並且設定了-l標誌,它返回行數。這使您可以將許多命令連結在一起。

但是,有時所需的內容可能會變得非常複雜,並且將命令連結在一起可能變得笨拙。在這種情況下,shell指令碼就是答案。Shell指令碼是由Shell讀取並按順序執行的命令列表。Shell指令碼還支援某些程式語言基礎知識,例如變數,流控制和資料結構。Shell指令碼對於將經常重複執行的批處理作業非常有用。不幸的是,shell指令碼有一些缺點:

Shell指令碼很容易變得過於複雜,並且對於想要改進或維護它們的開發人員來說是不可讀的。

這些shell指令碼的語法和直譯器通常很笨拙且不直觀。語法越笨拙,對於必須使用這些指令碼的開發人員來說,可讀性就越差。

該程式碼通常無法在其他指令碼中使用。指令碼之間的程式碼重用往往很困難,並且指令碼往往非常特定於某個問題。

用於高階功能(例如HTML解析或HTTP請求)的庫不像現代程式設計和指令碼語言那樣容易獲得。

這些問題會使shell指令碼難以處理,並經常導致大量開發人員時間浪費。取而代之的是,Python程式語言可以用作非常有力的替代品。使用Python代替Shell指令碼有很多好處:

預設情況下,所有主要的Linux發行版都安裝了Python。開啟命令列並立即鍵入python,將使您進入Python直譯器。這種普遍性使它成為大多數指令碼任務的明智選擇。

Python具有非常易於閱讀和理解的語法。它的風格強調簡約和簡潔的程式碼,同時允許開發人員以適合shell指令碼的準系統風格進行編寫。

Python是一種解釋型語言,這意味著沒有編譯階段。這使Python成為編寫指令碼的理想語言,它允許您以解釋的方式快速嘗試新程式碼。這使開發人員可以快速修改,而不必將整個程式寫到檔案中。

Python是一種功能齊全的程式語言。程式碼重用很簡單,因為Python模組可以輕鬆匯入並在任何Python指令碼中使用。指令碼可以輕鬆擴充套件或構建。

Python可以使用出色的標準庫和數以千計的第三方庫來處理各種高階實用程式,例如解析器和請求庫。例如,Python的標準庫包括日期時間庫,該庫允許將日期解析為指定的任何格式並將其與其他日期輕鬆比較。

但Python不應替換所有bash命令。編寫以UNIX方式執行的Python程式(即讀入標準輸入並寫入標準輸出)與為現有的shell命令(如cat和sort)編寫Python替代品一樣強大。

讓我們以本文前面已解決的問題為基礎。除了已經完成的工作之外,讓我們找出某個使用者已登入系統的次數。uniq命令僅刪除重複項,但不提供有關有多少重複項的資訊。代替uniq,Python指令碼可以用作鏈中的另一個命令。這是一個執行此操作的Python程式(在我的示例中,我將此檔案稱為namescount.py):

#!/usr/bin/env python
import sys

if __name__ == "__main__":
  # Initialize a names dictionary as empty to start with.
  # Each key in this dictionary will be a name and the value
  # will be the number of times that name appears.
  names = {}
  # sys.stdin is a file object. All the same functions that
  # can be applied to a file object can be applied to sys.stdin.
  for name in sys.stdin.readlines():
      # Each line will have a newline on the end
      # that should be removed.
      name = name.strip()
      if name in names:
          names[name] += 1
      else:
          names[name] = 1

  # Iterating over the dictionary,# print name followed by a space followed by the
  # number of times it appeared.
  for name,count in names.iteritems():
      sys.stdout.write("%d\t%s\n" % (count,name))
#!/usr/bin/env python

import sys

if __name__ == "__main__" :

 # Initialize a names dictionary as empty to start with.

 # Each key in this dictionary will be a name and the value

 # will be the number of times that name appears.

 names = { }

 # sys.stdin is a file object. All the same functions that

 # can be applied to a file object can be applied to sys.stdin.

 for name in sys . stdin . readlines ( ) :

 # Each line will have a newline on the end

 # that should be removed.

 name = name . strip ( )

 if name in names :

 names [ name ] += 1

 else :

 names [ name ] = 1

 # Iterating over the dictionary,# print name followed by a space followed by the

 # number of times it appeared.

 for name,count in names . iteritems ( ) :

 sys . stdout . write ( "%d\t%s\n" % ( count,name ) )

讓我們看看這個Python指令碼如何適合命令鏈。首先,它從通過 sys.stdin 物件公開的標準輸入中讀取輸入。任何輸出都將寫入 sys.stdout 物件,這是在Python中實現標準輸出的方式。Python字典(在其他語言中通常稱為雜湊對映)用於獲取從使用者名稱到重複計數的對映。要獲得所有使用者的數量,請執行以下操作:

$ cat names.log | python namescount.py
$ cat names . log | python namescount . py

顯示使用者出現的次數以及使用者名稱的計數。接下來要做的是按順序顯示最常使用該系統的使用者。這可以在Python級別完成,但是讓我們使用核心UNIX實用程式已經提供的實用程式來實現它。以前,我使用 sort 命令對字母進行排序。如果命令提供了 -rn 標誌,它將按降序對行進行數字排序。隨著Python指令碼按標準輸出,只需將命令通過管道傳遞到 sort 並檢索所需的輸出:

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

這是將Python用作命令鏈一部分的強大示例。在這種情況下使用Python的優點如下:

  • 與cat和sort等工具連結的能力。簡單的實用程式(逐行讀取檔案並以數字方式對檔案進行排序)由久經考驗的UNIX命令處理。這些命令也逐行讀取,這意味著這些功能可以縮放到大型檔案,而且速度很快。
  • 當需要在鏈中進行一些繁重的工作時,可以編寫一個非常清晰,簡潔的Python指令碼,該指令碼將執行其所需的工作,然後將責任轉移給鏈中的下一個連結。
  • 它是一個可重用的模組,儘管此示例專門針對名稱,但是如果您向此輸入中包含重複行的任何輸入,它將打印出每行和重複的數量。通過將Python程式碼模組化,可以將其應用於各種場景。

為了展示以模組化和管道方式組合Python指令碼的強大功能,讓我們進一步把問題放大。讓我們找到該服務的前五名使用者。 head 是一個命令,它允許您指定一定數量的行以顯示給定的標準輸入。將其新增到命令鏈中將得到以下內容:

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

這僅顯示前五個使用者,而忽略其餘使用者。同樣,要使五個使用者最少使用該服務,可以使用 tail 命令,該命令採用相同的引數。將Python命令列印到標準輸出的結果使可以構建和擴充套件其功能。

以上就是簡單的介紹,實際中大家靈活運用就好。

以上就是Python和Bash結合在一起的方法的詳細內容,更多關於python和bash結合的資料請關注我們其它相關文章!