用Python調用Shell命令


Python經常被稱作“膠水語言”,因為它能夠輕易地操作其他程序,輕易地包裝使用其他語言編寫的庫,也當然可以用Python調用Shell命令。

用Python調用Shell命令有如下幾種方式:

第一種:os.system

os.system("The command you want").

 

 

這個調用相當直接,且是同步進行的,程序需要阻塞並等待返回。返回值是依賴於系統的,直接返回系統的調用返回值,所以windows和linux是不一樣的。

 

第二種:os.popen

os.popen(command[,mode[,bufsize]])

先給大家看個例子

可以看出,popen方法通過p.read()獲取終端輸出,而且popen需要關閉close().當執行成功時,close()不返回任何值,失敗時,close()返回系統返回值. 可見它獲取返回值的方式和os.system不同。

 

 

第三種,使用commands ( python3失效)

根據你需要的不同,commands模塊有三個方法可供選擇。getstatusoutput, getoutput, getstatus。

commands.getstatusoutput(cmd) 返回(status, output).
commands.getoutput(cmd) 只返回輸出結果
commands.getstatus(file) 返回ls -ld file的執行結果字符串,調用了getoutput,不建議使用此方法

但是,如上三個方法都不是Python推薦的方法,而且在Python3中其中兩個已經消失。

 

第四種,subprocess《Python文檔中目前全力推薦》

subprocess使用起來同樣簡單:

直接調用命令,返回值即是系統返回。shell=True表示命令最終在shell中運行。Python文檔中出於安全考慮,不建議使用shell=True。建議使用Python庫來代替shell命令,或使用pipe的一些功能做一些轉義。官方的出發點是好的,不過真心麻煩了很多, so....

 

但是,我使用subprocess失敗了

>>> import subprocess
>>> subprocess.call("cat %s |grep %s > %s " % ("/home/www/running/os-app-api/nohup.out","2019-10-28","~/nohup-2019-10-28.out"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/subprocess.py", line 287, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/lib64/python3.6/subprocess.py", line 729, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.6/subprocess.py", line 1364, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'cat /home/www/running/os-app-api/nohup.out |grep 2019-10-28 > ~/nohup-2019-10-28.out ': 'cat /home/www/running/os-app-api/nohup.out |grep 2019-10-28 > ~/nohup-2019-10-28.out '

但是。。我可以直接運行在shell里面:

同樣的 我用os.system 去運行,也確實產生了。。好奇

>>> import os
>>> os.system("cat %s |grep %s > %s " % ("/home/www/running/os-app-api/nohup.out","2019-10-28","~/nohup-2019-10-28.out"))
256

 源碼研究:

這里面最為重要的幾個參數是:.
args:要執行的shell命令,或者是命令的列表;
bufsize:緩沖區大小;。
stdin、stdout、stderr:表示程序的標准輸入、標准輸出以及錯誤輸出。
shell:是否直接執行命令,如果設置為True就表示可以直接執行;
cwd:當前的工作目錄;
env:子進程環境變量;

案例:

 

 subprocess模塊里面還有一項功能比較強大的支持在於可以直接使用標准輸入、標准輸出和錯誤輸出進行進程的數據通訊操作。

    例如,在Python安裝完成之后都會存在有交互式的編程環境,那么本次將通過程序調用交互式編程環境。

直接操作python命令行,在python命令行中直接輸入程序。

def main():
    subp_popen=subprocess.Popen("python.exe",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

    subp_popen.stdin.write("print('subp_popen.stdin.write1')\n".encode())
    subp_popen.stdin.write("print('subp_popen.stdin.write2')\n".encode())
    subp_popen.stdin.write(("print('subp_popen.stdin.write3'+1)").encode())
    subp_popen.stdin.close()

    cmd_out=subp_popen.stdout.read()
    subp_popen.stdout.close()
    print(cmd_out.decode())

    cmd_err=subp_popen.stderr.read()
    subp_popen.stderr.close()
    print(cmd_err)

if __name__ == '__main__':

    main()

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM