使出Python的六脈神劍,讓Python擁有無限擴展性

爲了讓更多的人看到本文,請各位讀者動動小手,點擊右上角【...】,將本文分享到朋友圈,thanks! 

咱們知道,Python的API很是多,功能很是強大,並且很是易用。Python之因此強大,一個重要緣由是由於Python很是容易與其餘編程語言交互。這就讓Python擁有了無限擴展性。就算Python沒法實現某個功能,能夠用其餘語言實現,而後Python直接調用便可。
Python與其餘編程語言交互,主要有以下兩種方法:
(1)調用動態庫,如.dll,.so等;
(2)直接執行外部命令,並接收外部命令的返回結果;
第1種方法我會在後面的文章中詳細討論,本文主要講解如何使用Python執行外部的命令,並傳遞參數和接收返回值,而後作更進一步的處理。本文將介紹6種執行外部命令的方法,並比較這6中方法的優缺點。史稱這6種執行外部命令的方法爲六脈神劍。
Python執行外部命令的6種方法:
1. system函數
基本的調用格式以下:
import osos.system("some_command with args");
system函數會將命令和參數傳遞給系統的Shell。這麼作很是好,由於您實際上能夠用這種方式一次運行多個命令,並設置管道和輸入/輸出重定向。例如:
import osos.system("cat command.py | grep -n subprocess > result.txt")
執行這段代碼,會在當前目錄生成一個result.txt文件。
儘管這樣作很方便,但必須手動處理轉義字符(例如空格等)。因此這樣作只是讓你簡單地運行Shell程序,而不是擴展程序的功能。
2.  popen函數
基本調用格式以下:
import osstream = os.popen("some_command with args")
popen函數與os.system函數的功能相同,只是popen函數提供了一個用於操做文件的對象,可用使用標準輸入輸出的方式來訪問文件中的數據。popen函數還有其餘3種變體,它們對I/O的處理略有不一樣。若是將全部內容都做爲字符串傳遞,那麼命令將傳遞到Shell程序;若是將它們做爲列表傳遞,則無需擔憂轉義任何內容。例如:
import osstream = os.popen("cat command.py | grep -n subprocess")print(type(stream))result = stream.readlines()print(type(result))print(result)
執行這段代碼,會輸出以下內容:
<class 'os._wrap_close'><class 'list'>['1:import subprocess\n', '2:subprocess.run(["ls", "-l"])\n', '5:subprocess.call(["ls", "-l"])\n', '8:os.system("cat command.py | grep -n subprocess > result.txt")\n']
咱們能夠看到,readlines方法以列表形式返回命令的執行結果。

3. Popen類
subprocess模塊的Popen類。該類可用於替換os.popen函數。但Popen類的缺點是因爲功能過於強大,因此使用起來稍微複雜一些。例如:
print(subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read())
這行代碼能夠用來替換下面的代碼:
print(os.popen("echo Hello World").read())
關於Popen類的一個更復雜的例子以下:
import subprocessp = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)for line in p.stdout.readlines(): print(line.decode("utf-8").strip())retval = p.wait()
這段代碼經過標準輸出的readlines方法讀取了ls命令返回結果的全部行,並將這些內容輸出到Console。最後用wait方法等待ls命令執行完,最後結束程序。
Popen類相對於popen函數的優點是將全部的選項都統一放在了Popen類中,而不是須要4個不一樣的popen函數完成這些工做。
4.call函數
來自subprocess模塊的call函數。與Popen類同樣,擁有相同的參數,但call函數只會等待命令執行完並提供返回代碼才結束。例如:
return_code = subprocess.call("echo Hello World", shell=True)print(return_code)
5. run函數
若是讀者使用的是Python 3.5或更高版本,則能夠使用新的subprocess.run函數,該函數與上面的代碼很是類似,可是更加靈活,並在命令完成執行後返回CompletedProcess對象。例如:
import subprocessresult = subprocess.run(["ls", "-l"])print(type(result))

6. 類C函數
os模塊還提供了與C語言相似的fork / exec / spawn函數,可是我不建議直接使用它們,例如:
import osprint(os.execl('/bin/ls', ' '))
最後,請注意,對於這些執行外部命令的方法,須要將這些命令執行後參數的字符串傳遞迴程序,有時須要對這些傳回的字符串進行轉移。若是你沒法徹底信任這些字符串,那麼有可能會帶來嚴重的安全隱患。例如,若是用戶正在輸入字符串的某些/任何部分。若是不肯定,請僅將這些方法與常量一塊兒使用。爲了更好地說明這一點,請看下面的代碼。
print(subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read())
咱們能夠想象,當用戶輸入了「I love your harddisk && rm -rf /」,這將刪除硬盤中的全部數據。因此若是你對用戶的輸入沒法徹底信任的話,請將變量user_input改爲常量,不讓用戶任意輸入。

- EOF -python

推薦閱讀   點擊標題可跳轉

1. 開發跨設備的鴻蒙(HarmonyOS) Appweb

2.鴻蒙(HarmonyOS)大神都喜歡玩命令行typescript

3.像極客同樣提取Android的Root權限shell

4.牛掰了!鴻蒙與Android完美融合,將鴻蒙設備當Android設備用
編程

5.【鴻蒙學院】鴻蒙App開發直播學員提問與回答swift


關注「極客起源」公衆號,加星標,不錯過精彩技術乾貨
安全


本文分享自微信公衆號 - 極客起源(geekculture)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。bash

相關文章
相關標籤/搜索