【命令】Python中的執行命令【原創】

 

參考

官方手冊

python中os.system、os.popen、subprocess.popen的區別

Python執行系統命令的方法 os.system(),os.popen(),commands

Python subprocess模塊功能與常見用法實例詳解

 

一、概要

由於之前接觸了一個項目,做發佈系統,其中需要去git拉代碼並且checkout到對應的Tag或者是分支,這就要求需要使用Python來執行系統命令,於是開始接觸到了Python中的執行命令

 

如果想要在Python中調用cmd指令,有四種方法:

  • os.system
  • os.popen
  • commands(Python3已廢除)
  • subprocess模塊

 

二、os.system

用來執行cmd指令,在cmd輸出的內容會直接在控制檯輸出,返回結果爲0表示執行成功

system()函數在執行過程中進行了以下三步操作:

  • fork一個子進程
  • 在子進程中調用exec函數去執行命令
  • 在父進程調用wait(阻塞)去等待子進程結束

對於fork失敗,system函數會返回-1

 

注意: 由於使用該函數經常會莫名其妙地出現錯誤,但是直接執行命令並沒有問題,所以一般建議不要使用。

注意:os.system是簡單粗暴的執行cmd指令,如果想獲取在cmd輸出的內容,是沒辦法獲到的

注意:在Unix,Windows都有效

 

三、os.popen

同樣是用來執行cmd指令,如果想獲取控制檯輸出的內容,那就用os.popen的方法了,popen返回的是一個file對象,跟open打開文件一樣操作了,r是以讀的方式打開

 

popen() 創建一個管道,通過fork一個子進程,然後該子進程執行命令。返回值在標準IO流中,該管道用於父子進程間通信。父進程要麼從管道讀信息,要麼向管道寫信息,至於是讀還是寫取決於父進程調用popen時傳遞的參數(w或r)

 

比如:

#!/usr/bin/python
import os

p=os.popen('ssh 10.3.16.121 ls')
x=p.read()
print x
p.close()

 

注意:能獲取到命令的執行內容,可以打印出來,但是獲取不到命令是否執行成功,只是單純輸出了命令的執行結果而已

注意:os.popen() 方法用於從一個命令打開一個管道。在Unix,Windows中有效

 

四、subprocess模塊

subprocess模塊是在2.4版本中新增的,官方文檔中描述爲可以用來替換以下函數:os.system、os.spawn、os.popen、popen2

 

參數既可以是string字符串,也可以是list列表

比如:

subprocess.Popen([“cat”,”test.txt”])
subprocess.Popen(“cat test.txt”, shell=True) 

對於參數是字符串,需要指定shell=True,官方建議使用list列表

 

參數有:

 

比如:subprocess.call代替os.system

執行命令,返回命令的結果和執行狀態,0或者非0

import subprocess

retcode = subprocess.call('ls -l', shell=True)
print(retcode)

 

比如:subprocess.getstatusoutput()

接受字符串形式的命令,返回 一個元組形式的結果,第一個元素是命令執行狀態,第二個爲執行結果

比如:

#執行正確
>>> subprocess.getstatusoutput('pwd')
(0, '/root')
#執行錯誤
>>> subprocess.getstatusoutput('pd')
(127, '/bin/sh: pd: command not found')

 

比如:subprocess.getoutput()

接受字符串形式的命令,返回執行結果

#執行正確
>>> res = subprocess.getoutput('pwd')
>>> res
'/d/software/laragon/www/test/AutoRelease'
#執行錯誤
>>> res = subprocess.getoutput('ip addr')
>>> res
"'ip' 不是內部或外部命令,也不是可運行的程序\n或批處理文件。"

以及還有check_output()、check_call()、run()等

 

以上subprocess使用的方法,都是對subprocess.Popen的封裝

 

五、代碼

注意:以下代碼在Windows執行,會有一些問題,最好是在Linux下運行

 

os.system

# -*- coding:utf-8 -*-
import os


def run_cmd(string):
    print("命令爲:" + cmd)
    return os.system(string)


path = 'D:/software/laragon/test/'
cmd = "cd %s && rm -rf ./*" % path
res1 = run_cmd(cmd)

if res1 != 0:
    print("命令出錯了")
else:
    print("命令成功了")

git_url = 'http://xxx/AutoRelease.git'
cmd = "cd %s && git clone %s" % (path, git_url)
res2 = run_cmd(cmd)
if res2 != 0:
    print("命令出錯了")
else:
    print("命令成功了")

tag = 'v20190824'
cmd = "cd %s/AutoRelease && git checkout %s" % (path, tag)
res3 = run_cmd(cmd)
if res3 != 0:
    print("命令出錯了")
else:
    print("命令成功了")

cmd = "ls -al"
res4 = run_cmd(cmd)
if res4 != 0:
    print("命令出錯了")
else:
    print("命令成功了")

# Windows下報錯,Linux下不報錯
cmd = "ip addr"
res5 = run_cmd(cmd)
if res5 != 0:
    print("命令出錯了")
else:
    print("命令成功了")

# Windows不報錯,Linux下報錯
cmd = "ipconfig"
res6 = run_cmd(cmd)
if res6 != 0:
    print("命令出錯了")
else:
    print("命令成功了")

 

os.popen

同樣是實現上面的內容,但是結果卻不同:

# -*- coding:utf-8 -*-
import os


def run_cmd(string):
    print("命令爲:" + cmd)
    output = os.popen(string)
    ret = output.read()
    output.close()
    return ret


path = 'D:/software/laragon/test/'
cmd = "cd %s && rm -rf ./*" % path
res1 = run_cmd(cmd)
print('命令的結果爲:' + res1 + "\r\n")

git_url = 'http://xxx/AutoRelease.git'
cmd = "cd %s && git clone %s" % (path, git_url)
res2 = run_cmd(cmd)
print('命令的結果爲:' + res2 + "\r\n")

tag = 'v20190824'
cmd = "cd %s/AutoRelease && git checkout %s" % (path, tag)
res3 = run_cmd(cmd)
print('命令的結果爲:' + res3 + "\r\n")

cmd = "ls -al"
res4 = run_cmd(cmd)
print('命令的結果爲:' + res4 + "\r\n")

cmd = "ip addr"
res5 = run_cmd(cmd)
print('命令的結果爲:' + res5 + "\r\n")

# Windows不報錯,Linux下報錯
cmd = "ipconfig"
res6 = run_cmd(cmd)
print('命令的結果爲:' + res6 + "\r\n")

 

這個Python運行後,只有第四條和第六條命令能打印出來結果,也就是ls -al和ipconfig能打印出來,其他的命令只能在控制檯看到輸出結果,卻打印不出來,並且也不知道執行的狀態是否成功

 

suprocess

# -*- coding:utf-8 -*-
import subprocess


def run_cmd(string):
    print("命令爲:" + cmd)
    (code, res) = subprocess.getstatusoutput(string)
    return code, res


path = 'D:/software/laragon/test/'
cmd = "cd %s && rm -rf ./*" % path
(code, res) = run_cmd(cmd)
if code != 0:
    print("命令出錯了")
else:
    print("命令成功了")
print('命令的結果爲:' + res + "\r\n")

git_url = 'http://xxx/AutoRelease.git'
cmd = "cd %s && git clone %s" % (path, git_url)
(code, res) = run_cmd(cmd)
if code != 0:
    print("命令出錯了")
else:
    print("命令成功了")
print('命令的結果爲:' + res + "\r\n")

tag = 'v20190824'
cmd = "cd %s/AutoRelease && git checkout %s" % (path, tag)
(code, res) = run_cmd(cmd)
if code != 0:
    print("命令出錯了")
else:
    print("命令成功了")
print('命令的結果爲:' + res + "\r\n")

cmd = "ls -al"
(code, res) = run_cmd(cmd)
if code != 0:
    print("命令出錯了")
else:
    print("命令成功了")
print('命令的結果爲:' + res + "\r\n")

cmd = "ip addr"
(code, res) = run_cmd(cmd)
if code != 0:
    print("命令出錯了")
else:
    print("命令成功了")
print('命令的結果爲:' + res + "\r\n")

# Windows不報錯,Linux下報錯
cmd = "ipconfig"
(code, res) = run_cmd(cmd)
if code != 0:
    print("命令出錯了")
else:
    print("命令成功了")
print('命令的結果爲:' + res + "\r\n")

 

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