佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > Python中判斷subprocess調(diào)起的shell命令是否結(jié)束

Python中判斷subprocess調(diào)起的shell命令是否結(jié)束

熱門標(biāo)簽:企業(yè)做大做強(qiáng) 硅谷的囚徒呼叫中心 呼叫中心市場需求 客戶服務(wù) 語音系統(tǒng) 百度AI接口 Win7旗艦版 電話運(yùn)營中心

前言

最近在使用subprocess遇到個問題,折騰了好半天才找到簡單的解決辦法,在這里記錄下。

環(huán)境

Python:2.7.10

庫:subprocess, logging

問題

使用subprocess的Popen類來執(zhí)行shell命令,要怎么樣才能知道命令執(zhí)行結(jié)束了,以此來執(zhí)行回調(diào)方法。

解決辦法

使用subprocess.Popen.poll方法來獲取命令的執(zhí)行情況。

poll方法的返回值有兩種情況   

1. 當(dāng)命令未運(yùn)行結(jié)束的時候,返回None   

2. 當(dāng)命令結(jié)束時,返回命令的返回值

演示

這里使用logging模塊來輔助顯示命令執(zhí)行時間

分別使用兩種調(diào)用shell命令的方式來測試

shell=True

shell=False

完整演示

補(bǔ)充:system函數(shù)返回(如何判斷調(diào)用的shell命令是否執(zhí)行成功)

例:

status = system("./test.sh");

1、先統(tǒng)一兩個說法:

(1)system返回值:指調(diào)用system函數(shù)后的返回值,比如上例中status為system返回值

(2)shell返回值:指system所調(diào)用的shell命令的返回值,比如上例中,test.sh中返回的值為shell返回值。

2、如何正確判斷test.sh是否正確執(zhí)行?

僅判斷status是否==0?或者僅判斷status是否!=-1?

都錯!

3、man中對于system的說明

RETURN VALUE

The value returned is -1 on error (e.g. fork() failed), and the return

status of the command otherwise. This latter return status is in the

format specified in wait(2). Thus, the exit code of the command will

be WEXITSTATUS(status). In case /bin/sh could not be executed, the

exit status will be that of a command that does exit(127).

看得很暈吧?

system函數(shù)對返回值的處理,涉及3個階段:

階段1:創(chuàng)建子進(jìn)程等準(zhǔn)備工作。如果失敗,返回-1。

階段2:調(diào)用/bin/sh拉起shell腳本,如果拉起失敗或者shell未正常執(zhí)行結(jié)束(參見備注1),原因值被寫入到status的低8~15比特位中。system的man中只說明了會寫了127這個值,但實(shí)測發(fā)現(xiàn)還會寫126等值。

階段3:如果shell腳本正常執(zhí)行結(jié)束,將shell返回值填到status的低8~15比特位中。

備注1:

只要能夠調(diào)用到/bin/sh,并且執(zhí)行shell過程中沒有被其他信號異常中斷,都算正常結(jié)束。

比如:不管shell腳本中返回什么原因值,是0還是非0,都算正常執(zhí)行結(jié)束。即使shell腳本不存在或沒有執(zhí)行權(quán)限,也都算正常執(zhí)行結(jié)束。

如果shell腳本執(zhí)行過程中被強(qiáng)制kill掉等情況則算異常結(jié)束。

如何判斷階段2中,shell腳本是否正常執(zhí)行結(jié)束呢?系統(tǒng)提供了宏:WIFEXITED(status)。如果WIFEXITED(status)為真,則說明正常結(jié)束。

如何取得階段3中的shell返回值?你可以直接通過右移8bit來實(shí)現(xiàn),但安全的做法是使用系統(tǒng)提供的宏:WEXITSTATUS(status)。

由于我們一般在shell腳本中會通過返回值判斷本腳本是否正常執(zhí)行,如果成功返回0,失敗返回正數(shù)。

所以綜上,判斷一個system函數(shù)調(diào)用shell腳本是否正常結(jié)束的方法應(yīng)該是如下3個條件同時成立:

(1)-1 != status

(2)WIFEXITED(status)為真

(3)0 == WEXITSTATUS(status)

注意:

根據(jù)以上分析,當(dāng)shell腳本不存在、沒有執(zhí)行權(quán)限等場景下時,以上前2個條件仍會成立,此時WEXITSTATUS(status)為127,126等數(shù)值。

所以,我們在shell腳本中不能將127,126等數(shù)值定義為返回值,否則無法區(qū)分中是shell的返回值,還是調(diào)用shell腳本異常的原因值。shell腳本中的返回值最好多1開始遞增。

判斷shell腳本正常執(zhí)行結(jié)束的健全代碼如下:

#include  stdio.h>
#include  stdlib.h> 
int main() 
{ 
    pid_t status;   
    status = system("./test.sh"); 
    if(status == -1)
    {
 printf("system error... \n");
     }
 else
 {
            if(WIFEXITED(status))
     {
                if(0 == WEXITSTATUS(status))
         {
                    printf("run  successfully... \n");
                }
  else
  {
                    printf("run failed %d \n",WEXITSTATUS(status));
                 }
             }
      else
     {
                printf("exit code %d \n",WEXITSTATUS(status));
            }
 }
    return 0;
 } 

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • 詳談python中subprocess shell=False與shell=True的區(qū)別
  • python3通過subprocess模塊調(diào)用腳本并和腳本交互的操作
  • python subprocess pipe 實(shí)時輸出日志的操作
  • 通過實(shí)例解析python subprocess模塊原理及用法
  • 使用python執(zhí)行shell腳本 并動態(tài)傳參 及subprocess的使用詳解
  • python中的subprocess.Popen()使用詳解
  • 解決python subprocess參數(shù)shell=True踩到的坑

標(biāo)簽:崇左 山西 喀什 海南 濟(jì)南 安康 山西 長沙

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Python中判斷subprocess調(diào)起的shell命令是否結(jié)束》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    克山县| 安丘市| 星座| 修武县| 洪雅县| 修文县| 长垣县| 富裕县| 隆德县| 郁南县| 临西县| 嘉禾县| 淄博市| 肇东市| 景东| 灵川县| 略阳县| 丽水市| 彝良县| 察哈| 阿克陶县| 平山县| 中牟县| 海原县| 杭锦后旗| 夏津县| 衡水市| 康保县| 碌曲县| 林芝县| 綦江县| 鲁山县| 阳城县| 商丘市| 门头沟区| 县级市| 高陵县| 满洲里市| 渭源县| 永平县| 宜昌市|