1. 程式人生 > >Python 中os.system() 與os.exec*() 的區別

Python 中os.system() 與os.exec*() 的區別

在用高通的平臺做Android開發時,Modem端的軟體經常需要手動Push進去,並且檔案有很多。用ADB命令手動Push進去很麻煩,所以寫了一個指令碼來幹活。
Modem的檔案都是以modem開頭的
modem.b00, modem.b10, modem_fw.b11, xxx

#!/usr/bin/env python

########################################################
#
# Author:  Winva
# Date: 2012-7-9
########################################################

'''
This script is used for pushing modem firmware to Phone.
PC dirctory fm/modemXXX, phone /system/etc/firmware
run $adb push XXX /system/etc/firmware
Current can run on Linux, for Window need change '/' to '\\'
'''

import sys
import re
import os

# find files and do push

help = '''Usage: AutoPush inputDirectoryPC matchString outputDirectoryPhone
matchString: string to match the file name
inputDirectoryPC:  directory that includes the input files
outputDirectoryPhone: directory in phone that the files are pushed to
Example: AutoPush ~/fm/ modem /system/etc/firmware
'''

def main():
    # check parameters
    argn = len(sys.argv)
    if argn == 1 :
        print 'You must input the input directory!'
        print help
        sys.exit()
    elif argn == 2 :
        path = sys.argv[1]
        matchString = 'modem'
        phoneDirectory = '/system/etc/firmware'
    elif argn == 3 :
        path = sys.argv[1]
        matchString = sys.argv[2]
        phoneDirectory = '/system/etc/firmware'
    else :
        path = sys.argv[1]
        matchString = sys.argv[2]
        phoneDirectory = sys.argv[3]

    if os.path.isdir(path) :
        print path
    else :
        print 'Error, %s not exist!' % path
        sys.exit()       


    # if path has a '/' for linux or '\\' for win?
    # in case of missing a '/'
    if path[-1] != '/' :
        path = path + '/'

    fileList = os.listdir(path)     
    foundFileNumber = 0
    for fileName in fileList :
        file = path + fileName
        print file
        # if the file is match?
        m = re.match(matchString, fileName)
        if m is not None :
            if os.path.isfile(file) :
                # Execute the operation 
                print 'Found a file: %s' % fileName
                os.execlp('adb','adb', 'push',file, phoneDirectory )

                foundFileNumber += 1

    print '%d files handled!' % foundFileNumber

if __name__ == '__main__':
  main()
  
執行程式:$ ./AutoPy.py firmware/
但是隻有一個檔案被Push進去了,看來是execlp()把Process搶走了,執行完了就退出了。
仔細查了一下Python的幫助
os.exec*()
The various exec*() functions take a list of arguments for the new program loaded into the process.   
These functions all execute a new program, replacing the current process; they do not return. On Unix, the new executable is loaded into the current process, and will have the same process id as the caller. Errors will be reported as OSError exceptions.
The current process is replaced immediately.
當前的shell會被Adb程式替代,所以執行一次就退出。

還有另外一個函式
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. 
這個命令是在subshell裡執行,執行完還會回到shell。

改成這樣就可以了:
                cmd = 'adb push ' + file + ' ' +  phoneDirectory
                os.system(cmd)