2019년 2월 21일 목요일

[Python] Shell Command


1. Shell Execute with subprocess.communicate()

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import sys
import os
import time
import select
import copy
import subprocess
import threading
from threading import *

def ShellExecute(cmd, timeout=None):
    
    si = subprocess.STARTUPINFO()
    si.dwFlags |= subprocess.STARTF_USESHOWWINDOW #|subprocess.STARTF_USESTDHANDLES
    si.wShowWindow = subprocess.SW_HIDE
        
    process = subprocess.Popen(cmd
        , shell=True
        , stdin=subprocess.DEVNULL
        , stdout=subprocess.PIPE
        , stderr=subprocess.PIPE
        , startupinfo=si
        )

    outs, errs = process.communicate(timeout=timeout)
        
    return process.returncode, outs, errs


2. Shell Execute with read()

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import sys
import os
import time
import select
import copy
import subprocess
import threading
from threading import *

def ShellExecuteRealTime(cmd, timeout=None):
    
    si = subprocess.STARTUPINFO()
    si.dwFlags |= subprocess.STARTF_USESHOWWINDOW #|subprocess.STARTF_USESTDHANDLES
    si.wShowWindow = subprocess.SW_HIDE
        
    process = subprocess.Popen(cmd
        , shell=True
        , stdin=subprocess.DEVNULL
        , stdout=subprocess.PIPE
        , stderr=subprocess.DEVNULL
        , startupinfo=si
        )

    outs = b''
    while True:
        char = process.stdout.read() # read(1), process.stderr.readline()
        if not char:
            break
        outs += char
        
    return process.returncode, outs


3. Shell Execute with Thread

1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
import sys
import os
import time
import select
import copy
import subprocess
import threading
from threading import *

class ShellExecuteThread(object):
    
    def __init__(self, cmd, timeout=None):
        self.cmd = cmd
        self.thread = None
        self.process = None
        self.timeout = timeout
        self.stdouts = None
        self.stderrs = None
        self.running = None
        self.lock = threading.Lock()

    def run(self, timeout=None):
        if timeout is not None:
            self.timeout = timeout
        def target():
            self.running = True
            si = subprocess.STARTUPINFO()
            si.dwFlags |= subprocess.STARTF_USESHOWWINDOW # |subprocess.STARTF_USESTDHANDLES
            si.wShowWindow = subprocess.SW_HIDE
            self.process = subprocess.Popen(self.cmd
                    , shell=True 
                    , stdout=subprocess.PIPE
                    , stderr=subprocess.PIPE                    
                    , startupinfo=si
                    , bufsize=0
                    , universal_newlines=True 
                    , encoding='euc-kr'
                    , text=True
                )
            self.stdouts, self.stderrs = self.process.communicate(self.timeout)
            self.running = False

        self.thread = threading.Thread(target=target)
        self.thread.start()
        
    def runwait(self, timeout=None):
        self.run(timeout)
        self.thread.join(self.timeout)
        if self.thread.is_alive():
            self.process.terminate()
            self.thread.join()

        return self.process.returncode, self.stdouts, self.stderrs

    def run_stdouts(self):
        def target():
            self.running = True
            word = b''
            while True:
                char = self.process.stdout.read(1) #readline()
                if not char:
                    break
                if self.process.poll() is not None:
                    break;
                word += char
                if char.isspace():
                    self.lock.acquire()
                    self.stdouts += word
                    self.lock.release() 
                    word = b''
            if len(word) > 0:
                self.lock.acquire()
                self.stdouts += word
                self.lock.release() 
            self.running = False
            
        si = subprocess.STARTUPINFO()
        si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        si.wShowWindow = subprocess.SW_HIDE
        self.process = subprocess.Popen(self.cmd
                , shell=True 
                , stdout=subprocess.PIPE
                , startupinfo=si
            )

        self.stdouts = b'';
        self.thread = threading.Thread(target=target)
        self.thread.start()
        
    def get_stdouts(self):
        if self.running == True or len(self.stdouts) > 0 is None:
            self.lock.acquire()
            outs = self.stdouts  #copy.deepcopy(self.stdouts)
            self.stdouts = b'';
            self.lock.release()            
            return outs
        else:
            return None
    
    def get_returncode(self):
        if self.process is not None:
            return self.process.returncode
        return None
    


4. Thread Example
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import sys
import os
import time
import select
import copy
import subprocess
import threading
from threading import *

class WorkerThread(Thread):
    
    def __init__(self, cmd, timeout=None):
        Thread.__init__(self)
        self.cmd = cmd
        self.stoprequest = threading.Event()
        self.start()

    def run(self):
        import subprocess
        global threadLock
        global line
        
        si = subprocess.STARTUPINFO()
        si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        si.wShowWindow = subprocess.SW_HIDE

        process = subprocess.Popen(self.cmd
                , shell=False 
                , stdin=subprocess.DEVNULL
                , stdout=subprocess.PIPE
                , stderr=subprocess.PIPE
                , startupinfo=si
                )

        while not self.stoprequest.isSet():
            char = process.stdout.read(1) #process.stderr.readline()
            if not char:
                break
            if process.poll() is not None:
                break;
            if char != b'\r': # accept only b'\n'
                self.lock.acquire()
                self.stdouts += char
                self.lock.release()    

        errcode = process.returncode
        if errcode is not None:
            raise Exception('cmd %s failed, see above for details', cmd)
        process.terminate()

    def stop(self, timeout=None):
        self.stoprequest.set()
        super(WorkerThread, self).join(timeout)



댓글 없음:

댓글 쓰기