https://docs.python.org/3/library/os.html
https://docs.python.org/3/library/subprocess.html
subprocess是對os.system的一個改進型模塊,建議實際中使用subprocess模塊內的命令來執行系統命令,關于他們之間的差別請詳細閱讀上述官方檔案,
一、os.system與os.popen
1. os.system(command)
Execute the command (a string) in a subshell. This is implemented by calling the Standard C function system(), and has the same limitations,
On Unix, the return value is the exit status of the process encoded in the format specified for wait(),
On Windows, the return value is that returned by the system shell after running command,
在unix和windows系統下其回傳值是不一樣的,unix下回傳一個returncode,而非執行結果,windows下則回傳執行結果,
os.system('ls')
2. os.popen(cmd, mode='r', buffering=-1)
Open a pipe to or from command cmd. The return value is an open file object connected to the pipe, which can be read or written depending on whether modeis 'r' (default) or 'w',
為要執行的命令開一個pipe,回傳值為此pipe(一般為一個打開的檔案),mode引數即為打開模式,可以從此檔案中讀取回傳的結果,
popen并不會等命令執行完畢,而是會直接回傳一個pipe端物件,正如上邊所說的,可以使用readlines等讀取已經寫入的內容,
例如:
tmp = os.popen('ls *.py').readlines()
# popen可以使用with背景關系語法來處理:
In [9]: with os.popen('ls') as p:
...: for l in p.readlines():
...: print(l.strip('\n'))
popen的好處在于:將回傳的結果存于臨時檔案中,便于程式處理,system()與popen()的區別則在于,前者需要等命令執行完畢才回傳,后者不會等子行程執行完畢,system()就相當于popen().wait(),后者也是回傳returncode, python3的官網已經說明了,os.popen是基于subprocess.Popen實作的:This is implemented using subprocess.Popen; 而在python2.7的官方檔案里說明了:Deprecated since version 2.6,即此方法自2.6以來已經被放棄了, 因此建議,使用subprocess.Popen來執行系統命令,
二、subprocess模塊
os模塊里還有很多其他重要的method,但是僅就執行系統命令來說,subprocess模塊是這項功能的改進版,
subprocess主要是run()方法和Popen()物件,前者在python3.5之前可能大多使用call(),在3.5之后使用run()來簡化,
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
Run the command described by args. Wait for command to complete, then return a CompletedProcess instance.
即run():執行指定的命令,等待執行結束并回傳一個CompletedProcess 實體物件,
import subprocess
subprocess.call (["cmd", "arg1", "arg2"],shell=True)
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)
Execute a child program in a new process. On POSIX, the class uses os.execvp()-like behavior to execute the child program. On Windows, the class uses the Windows CreateProcess() function.
即Popen():開啟一個子行程執行命令,
run與Popen的差別在于,前者是一個method,會在執行完命令然后回傳一個包含returncode和所執行的命令的CompletedProcess物件,后者則只是建好子行程,想要獲取結果就得使用此class的各種instance method,
在獲取執行結果方面有些類似于os.system與os.popen的差別,
而Popen class相對于os.popen的優勢在于,Popen是一個構造一個class instance,popen是一個method,一個instance顯然具有更多的選項,可以幫助我們更好的控制子行程,
import subprocess
p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
print(line)
retval = p.wait()
# Popen物件支持with背景關系寫法:
with subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as p:
for line in p.stdout.readlines():
print(line)
最后:
1.當執行命令的引數或者回傳中包含了中文字符,那么建議使用subprocess, 2.綜上所述,還是建議使用subprocess.Popen來執行系統命令,一方面Popen相比os.system()和subprocess.run()是非阻塞模式的,另一方面Popen相比os.popen()更加的靈活與全面,所以建議在執行作業系統命令時使用subprocess.Popen物件,并同時推薦其with寫法,轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/158674.html
標籤:Python
下一篇:九、Python入門-網路編程
