首頁 >後端開發 >Python教學 >Python下呼叫Linux的Shell指令

Python下呼叫Linux的Shell指令

高洛峰
高洛峰原創
2016-11-23 13:04:141438瀏覽

有時候難免需要直接呼叫Shell指令來完成一些比較簡單的操作,像是mount一個檔案系統之類的。那我們使用Python如何呼叫Linux的Shell指令?以下來介紹幾個常用的方法:

1. os 模組

 

1.1. os模組的exec方法族

Python的exec系統方法同Unix的exec系統呼叫是一致的。這些方法適用 於在子進程中呼叫外部程式的情況,因為外部程式會取代目前進程的程式碼,不會回傳。 ( 這個看了點help(os)  --> search "exec" 的相關介紹,但是沒太搞明白咋使用)

 

1.2. os模組的system方法

system方法會創建子進程運行外部程式,方法只傳回外部程式的運行結果。這個方法比較適用於外部程式沒有輸出結果的情況。

[python] view plaincopy

>>> import os  

>>> os.system("echo "Hello World    ————— —> 列印指令結果  

0                   ----> What's this  ??

>>> val = os.system("ls -al | grep "log" ")   # 使用val接收回值  

9 Dec 31 15:14 log    — —————> 此時只列印了指令結果  

>>> print val              

0    是0  

>>> val = os.system("ls -al | grep "log1" ")  

>>> print val         呼叫一個沒有回傳結果的指令,回傳值為256~  

>>>   

注意:上面說了,此方法脂肪會外部程序的結果,也就是os.system的結果,所以如果你想接收命令的回傳值,接著向下看~

 

1.33 . os模組的popen方法

當需要得到外部程式的輸出結果時,本方法非常有用,傳回一個類別檔案對象,呼叫該物件的read()或readlines()方法可以讀取輸出內容。例如使用urllib呼叫Web API時,就需要對得到的資料進行處理。 os.popen(cmd) 要得到指令的輸出內容,只要再呼叫下read()或readlines()等如a=os.popen(cmd).read()

 

[python] view plaincopy

>>> os.popen('ls -lt')                  # 調用os.popen(cmd)沒有5ee8>  

> >> print os.popen('ls -lt').read()     # 呼叫read()方法可以取得指令的結果  

total 6064        23 Jan  5 21:00 hello .sh  

-rw-r--r-- 1 long       long            147 Jan  

drwxr-xr-x 3 long       long          4096 Jan  2 19:37 testo     6030829 Dec 31 15:14 log  

drwxr-xr-x 2 long       long   2 long   09:36 pip_build_long  

drwx------ 2 Debian-gdm Debian-gdm    4096 Dec 23 19:08 pulsese-GUdr123 .    long          4096 Jan  1  1970 orbit-long  

>>> val = os.popen('ls -lt').read()     # 使用變數使用in來判斷回傳值中有木有一個字串  

...     print "Haha,there is the log"  

... else:   

Haha,there is the log  

2. commands 模組

使用commands模組的getoutput方法,此方法是同popend的區別在於popen

使用commands模組的getoutput方法,此方法將外部程式輸出的區別在於popen」是一個類別檔案作字串返回,很多情況下用起來要更方便。

主要方法:  

*   commands.getstatusoutput(cmd)         返回(status, output)

*   commands.getoutput(cmd)   getstatus(file)                     返回ls -ld file的執行結果字串,呼叫了getoutput,不建議使用此方法

 

[python] view plaincopy

long@zhouyl:/tmp/tests$ python  

 

[GCC 4.7.2] on linux2  


Type "help", "copyright", "credits" or "license" for more information. statusoutput('ls -lt ')      # 返回(status, output)  

(0, 'total 5900n-rwxr-xr-x 1 long long  long long     147 Jan  5 21:34 Makefilen-rw-r--r-- 1 long long 6030829 Jan  5 21:34 log')  

>>結果(貌似和Shell指令的輸出格式不同哈~)  

'total 5900n-rwxr-xr-x 1 long long      23 Jan  5 21:34 hello.shn-143 Jan  5 21:34 Makefilen -rw-r--r-- 1 long long 6030829 Jan  5 21:34 log'  

>>>進行相同的操作

'-rw-r--r-- 1 long long 6030829 Jan  5 21:34 log'  

>>>   官方文件說明,subprocess模組用於取代上面這些模組。有一個用Python實現的平行ssh工具—mssh,程式碼很簡短,不過很有意思,它在執行緒中呼叫subprocess啟動子程序來工作。

[python] view plaincopy

>>> from subprocess import call  

>>> call(["ls", "-l"])  


subprocess與system相比的優點是它更靈活(你可以得到標準輸出,標準錯誤,「真正」的狀態碼,更好的錯誤處理,等..)。我認為使用os.system已過時,或即將過時。

4. 眾方法的比較以及總結

4.1. 關於os.system 

os.system("some_command with args")將命令以及參數傳遞給你的系統shell,這很好,因為你可以用這種方法同時運行多個命令並且可以設定管道以及輸入輸出重定向。例如:
os.system("some_command output_file")
然而,雖然這很方便,但是你需要手動處理shell字元的轉義,例如空格等。此外,這也只能讓你執行簡單的shell指令而且不能執行外部程式。

4.2. 關於os.popen

使用stream = os.popen("some_command with args")也能做與os.system一樣的事,與os.system不同的是os.popen會回傳一個類文件對象,使用它來存取標準輸入、輸出。

4.3. 關於subprocess.popen

subprocess模組的Popen類,意圖作為os.popen的替代,但是因為其很全面所以比os.popen要顯得稍微複雜。
例如你可以用  print Popen("echo Hello World", stdout=PIPE, shell=True).stdout.read()  來取代  print os.popen("echo Hello World").read()。但相較之下它使用一個統一的類別包括4中不同的popen函數還是不錯的。

4.4. 關於subprocess.call

subprocess模組的call函數。它基本上就像Popen類別並且都使用相同的參數,但是它只簡單的等待命令完成並給你返回程式碼。例如:
return_code = subprocess.call("echo Hello World", shell=True)


os模組中還有C中那樣的fork/exec/spawn函數,但是我不建議直接使用它們。 subprocess可能更適合你。


===========================================
[1] http://demi-panda.com/2013/01/25/python-shell-command/index.html
[2] http://m.blog.csdn.net/blog/overstack/9295995
[3] http://blog.csdn.net/swiftshow/article/details/7755543

下面是文中所涉及的內容的python官方文件:

[4] http://docs.python.org/library/subprocess .html#replacing-older-functions-with-the-subprocess-module       -- 關於使用subprocess 替代舊的方法

[5] http://docs.python.org/lib/os-process.html     --os的exec方法族以及system方法

[6] http://docs.python.org/lib/os-newstreams.html    -- os的popen方法

[7] http://docs.python.org/ lib/node528.html    -- os的subprocess介紹


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn