python中那糾結的os.system()與空格處理

原貼地址:http://www.cnblogs.com/ini_always/archive/2011/09/26/2192205.html


今天在寫一個用來對vmware workstation虛擬機進行操作的小腳本,主要原理是用python來調用vmrun.exe,傳遞各種不同的參數給它,來進行不同的操作。

原理很簡單,實現。。。其實也很簡單,你會說:不就是一個os.system()調用嗎?是的,我也是這麼想的。

我把vmware裝在program files目錄下,其完整路徑爲:C:\Program Files\VMware\VMware Workstation\vmrun.exe,你肯定注意到了,路徑中有空格,於是,你會說,那加個雙引號括起來不就行了嘛。是的,我也是這麼想的。

但是關鍵是,我們都這麼想,程序不這麼想,運行時,程序報出'C:\Program' is not recognized as an internal or external command, operable program or batch file.的錯誤,這一看就是典型的路徑中存在空格的錯誤,你會懷疑說,你加引號沒?我的第一反應也是懷疑加引號沒?但這個確實加了。

不管你糊塗沒有,反正我到這一步是糊塗了,既然引號加了,但從結果來看,os.system()還是用空格把字符串給拆成了不同的部分,然後再調用shell來執行。但我後來在實驗的過程中又發現了一個奇怪的問題:如果參數只是一個加引號的字符串,os.system()就可以正常執行,但如果有多個引號對,就會出現以上錯誤。也就是說,如果參數類似"xx yy zz"這樣的類型,os.system()可以成功執行;如果參數類似"xx yy" "aa bb"這樣的類型,os.system()就會出錯。

這一下子引起了我的好奇心,想去看看os.system()的源代碼是怎麼處理的,但死活沒有找到,唉,又要被這該死的好奇心折磨了。

最後說一下解決方法,就是用subprocess.Popen()代替os.system(),如下:

ps = subprocess.Popen(cmd);
ps.wait(); #讓程序阻塞

最最後,附上python中對os.system()函數的說明:

複製代碼
Execute the command (a string) in a subshell. This is implemented by calling the Standard C function system(),
and has the same limitations
. Changes to posix.environ, sys.stdin, etc. are not reflected in the environment
of the executed command.

On Unix, the return value is the exit status of the process encoded in the format specified for wait(). Note
that POSIX does not specify the meaning of the return value of the C system() function, so the return value
of the Python function is system-dependent.


On Windows, the return value is that returned by the system shell after running command, given by the Windows
environment variable COMSPEC: on command.com systems (Windows 95, 98 and ME) this is always 0; on cmd.exe
systems (Windows NT, 2000 and XP) this is the exit status of the command run; on systems using a non-native
shell, consult your shell documentation.


Availability: Macintosh, Unix, Windows.

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results;
using that module is preferable to using this function.
複製代碼

可以看出,os.system()是調用了C語言的標準函數system(),不過那個那個紅紅的limitations單詞說明這個方法有其侷限性。最後一句話話說,subprocess模塊更加強大,並建議我們儘量使用subprocess模塊。

所以,應該儘量不要使用os.system()方法,而是用subprocess中的Popen對象或者call()方法代替,以免產生不可預知的錯誤。

==================================我是剛猛的分界線==================================

寫完文章,才發現python的官方網站上有人提交這個bug:http://bugs.python.org/issue1524,不過這個bug在07年就提交了,但看結果是wont fix(不會修復),看後面的評論,原來是os.system()只是簡單地把字符串傳遞給system()函數,自己並不會對字符串進行處理,所以這個bug應該是system()函數的問題或者windows shell的問題,這確實不是python能修復的。  ^_^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章