時(shí)候難免需要直接調(diào)用Shell命令來完成一些比較簡單的操作,比如mount一個(gè)文件系統(tǒng)之類的。那么我們使用Python如何調(diào)用Linux的Shell命令?下面來介紹幾種常用的方法:
1. os 模塊
1.1. os模塊的exec方法族
Python的exec系統(tǒng)方法同Unix的exec系統(tǒng)調(diào)用是一致的。這些方法適用于在子進(jìn)程中調(diào)用外部程序的情況,因?yàn)橥獠砍绦驎?huì)替換當(dāng)前進(jìn)程的代碼,不會(huì)返回。( 這個(gè)看了點(diǎn) help(os) --> search "exec" 的相關(guān)介紹,但是沒太搞明白咋使用)
1.2. os模塊的system方法
system方法會(huì)創(chuàng)建子進(jìn)程運(yùn)行外部程序,方法只返回外部程序的運(yùn)行結(jié)果。這個(gè)方法比較適用于外部程序沒有輸出結(jié)果的情況。
>>> import os >>> os.system("echo /"Hello World/"") # 直接使用os.system調(diào)用一個(gè)echo命令 Hello World ――――――> 打印命令結(jié)果 0 ――――――> What's this ? 返回值? >>> val = os.system("ls -al | grep /"log/" ") # 使用val接收返回值 -rw-r--r-- 1 root root 6030829 Dec 31 15:14 log ――――――> 此時(shí)只打印了命令結(jié)果 >>> print val 0 ――――――> 注意,此時(shí)命令正常運(yùn)行時(shí),返回值是0 >>> val = os.system("ls -al | grep /"log1/" ") >>> print val 256 ――――――> 使用os.system調(diào)用一個(gè)沒有返回結(jié)果的命令,返回值為256~ >>> 注意:上面說了,此方法脂肪會(huì)外部程序的結(jié)果,也就是os.system的結(jié)果,所以如果你想接收命令的返回值,接著向下看~
1.3. os模塊的popen方法
當(dāng)需要得到外部程序的輸出結(jié)果時(shí),本方法非常有用,返回一個(gè)類文件對象,調(diào)用該對象的read()或readlines()方法可以讀取輸出內(nèi)容。比如使用urllib調(diào)用Web API時(shí),需要對得到的數(shù)據(jù)進(jìn)行處理。os.popen(cmd) 要得到命令的輸出內(nèi)容,只需再調(diào)用下read()或readlines()等 如a=os.popen(cmd).read()
>>> os.popen('ls -lt') # 調(diào)用os.popen(cmd)并不能得到我們想要的結(jié)果 <open file 'ls -lt ', mode 'r' at 0xb7585ee8> >>> print os.popen('ls -lt').read() # 調(diào)用read()方法可以得到命令的結(jié)果 total 6064 -rwxr-xr-x 1 long long 23 Jan 5 21:00 hello.sh -rw-r--r-- 1 long long 147 Jan 5 20:26 Makefile drwxr-xr-x 3 long long 4096 Jan 2 19:37 test -rw-r--r-- 1 root root 6030829 Dec 31 15:14 log drwxr-xr-x 2 long long 4096 Dec 28 09:36 pip_build_long drwx------ 2 Debian-gdm Debian-gdm 4096 Dec 23 19:08 pulse-gylJ5EL24GU9 drwx------ 2 long long 4096 Jan 1 1970 orbit-long >>> val = os.popen('ls -lt').read() # 使用變量可以接收命令返回值 >>> if "log" in val: # 我們可以使用in來判斷返回值中有木有一個(gè)字符串 ... print "Haha,there is the log" ... else: ... print "No,not happy" ... Haha,there is the log 2. commands 模塊
使用commands模塊的getoutput方法,這種方法同popend的區(qū)別在于popen返回的是一個(gè)類文件對象,而本方法將外部程序的輸出結(jié)果當(dāng)作字符串返回,很多情況下用起來要更方便些。
主要方法:
* commands.getstatusoutput(cmd) 返回(status, output)
* commands.getoutput(cmd) 只返回輸出結(jié)果
* commands.getstatus(file) 返回ls -ld file的執(zhí)行結(jié)果字符串,調(diào)用了getoutput,不建議使用此方法
long@zhouyl:/tmp/tests$ python Python 2.7.3 (default, Jan 2 2013, 16:53:07) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import commands >>> commands.getstatusoutput('ls -lt') # 返回(status, output) (0, 'total 5900/n-rwxr-xr-x 1 long long 23 Jan 5 21:34 hello.sh/n-rw-r--r-- 1 long long 147 Jan 5 21:34 Makefile/n-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log') >>> commands.getoutput('ls -lt') # 返回命令的輸出結(jié)果(貌似和Shell命令的輸出格式不同哈~) 'total 5900/n-rwxr-xr-x 1 long long 23 Jan 5 21:34 hello.sh/n-rw-r--r-- 1 long long 147 Jan 5 21:34 Makefile/n-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log' >>> commands.getstatus('log') # 調(diào)用commands.getoutput中的命令對'log'文件進(jìn)行相同的操作 '-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log' >>> 3. subprocess模塊
根據(jù)Python官方文檔說明,subprocess模塊用于取代上面這些模塊。有一個(gè)用Python實(shí)現(xiàn)的并行ssh工具―mssh,代碼很簡短,不過很有意思,它在線程中調(diào)用subprocess啟動(dòng)子進(jìn)程來干活。
>>> from subprocess import call
>>> call(["ls", "-l"])
subprocess與system相比的優(yōu)勢是它更靈活(你可以得到標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤,“真正”的狀態(tài)代碼,更好的錯(cuò)誤處理,等..)。我認(rèn)為使用os.system已過時(shí),或即將過時(shí)。
4. 眾方法的比較以及總結(jié)
4.1. 關(guān)于 os.system
os.system("some_command with args")將命令以及參數(shù)傳遞給你的系統(tǒng)shell,這很好,因?yàn)槟憧梢杂眠@種方法同時(shí)運(yùn)行多個(gè)命令并且可以設(shè)置管道以及輸入輸出重定向。比如:
os.system("some_command < input_file | another_command > output_file")
然而,雖然這很方便,但是你需要手動(dòng)處理shell字符的轉(zhuǎn)義,比如空格等。此外,這也只能讓你運(yùn)行簡單的shell命令而且不能運(yùn)行外部程序。
4.2. 關(guān)于os.popen
使用stream = os.popen("some_command with args")也能做與os.system一樣的事,與os.system不同的是os.popen會(huì)返回一個(gè)類文件對象,使用它來訪問標(biāo)準(zhǔn)輸入、輸出。
4.3. 關(guān)于subprocess.popen
subprocess模塊的Popen類,意圖作為os.popen的替代,但是因?yàn)槠浜苋嫠员萶s.popen要顯得稍微復(fù)雜。
比如你可以使用 print Popen("echo Hello World", stdout=PIPE, shell=True).stdout.read() 來替代 print os.popen("echo Hello World").read()。但是相比之下它使用一個(gè)統(tǒng)一的類包括4中不同的popen函數(shù)還是不錯(cuò)的。
4.4. 關(guān)于subprocess.call
subprocess模塊的call函數(shù)。它基本上就像Popen類并都使用相同的參數(shù),但是它只簡單的等待命令完成并給你返回代碼。比如:
return_code = subprocess.call("echo Hello World", shell=True)
os模塊中還有C中那樣的fork/exec/spawn函數(shù),但是我不建議直接使用它們。subprocess可能更加適合你。
python和shell讀取文件某一行
python和shell(awk命令) 可以實(shí)現(xiàn)直接讀取文件的某一行,按行號進(jìn)行讀取 。并可以精準(zhǔn)的取得該行的某個(gè)字段,這個(gè)有點(diǎn)類似于x軸、y軸定位某個(gè)點(diǎn)的操作。
一、awk取某行某列值
awk 可以設(shè)置條件來輸出文件中m行到n行中每行的指定的k字段,使用格式如下:
awk 'NR==m,NR==n {print $k}' path/filenamem,n,k表示實(shí)在的數(shù)值。如果要用變量來表示m,n的值,則變量需要用單引號將其引起來。NR,{print }是awk命令在此用法下的規(guī)定字段;path/filename表示讀取文件的路徑及文件名。這里指定了兩行,如果只指定一行,可以這樣寫:
awk 'NR==m {print $k}' path/filename二、python取某行某列
標(biāo)準(zhǔn)庫提供的linecache模塊提供具體取某一行的方法:
import linecachetheline = linecache.getline(filepath, line_number)
取到相關(guān)的行以后,再對theline做split切分成list,再對list索引取值就行了。如theline.split()[2] 。
三、linecache模塊的用法
即然,提到了linecache模塊,這里就列下linecache的其他方法。linecache模塊允許從任何文件里得到任何的行,并且使用緩存進(jìn)行優(yōu)化,常見的情況是從單個(gè)文件讀取多行。
linecache.getlines(filename) 從名為filename的文件中得到全部內(nèi)容,輸出為列表格式,以文件每行為列表中的一個(gè)元素,并以linenum-1為元素在列表中的位置存儲
linecache.getline(filename,lineno) 從名為filename的文件中得到第lineno行。這個(gè)函數(shù)從不會(huì)拋出一個(gè)異常
主站蜘蛛池模板:
双流县|
精河县|
阿克苏市|
松江区|
津南区|
宕昌县|
云梦县|
晴隆县|
高淳县|
宜兴市|
平江县|
津市市|
蚌埠市|
昌吉市|
韶山市|
金塔县|
陆川县|
祥云县|
丹江口市|
亳州市|
栾城县|
乃东县|
荆州市|
伊宁县|
阜城县|
固始县|
十堰市|
山丹县|
中阳县|
招远市|
苗栗市|
武川县|
彰化县|
江津市|
通海县|
禹城市|
修武县|
张家川|
和龙市|
金昌市|
友谊县|