How to make subprocess error message

We have created a product function used in many projects that uses a subprocess to run a team. This function is as follows:

def _popen( command_list ):
    p = subprocess.Popen( command_list, stdout=subprocess.PIPE,
        stderr=subprocess.PIPE )

    out, error_msg = p.communicate()

    # Some processes (e.g. system_start) print a number of dots in stderr
    # even when no error occurs.
    if error_msg.strip('.') == '':
        error_msg = ''

    return out, error_msg

For most processes, this works as intended.

But now I have to use it with a background process that should work as long as my python-script is working, and now the fun begins ;-).
Note: the script also needs to start other non-phonic processes using the same _popen function.

I know that by skipping p.communicate, I can start the process in the background while my python script continues.
But there are two problems:

  • I need to check that the background process is running correctly.
  • , stdout stderr , / .


1 _popen "skip_com" ( False), p.communic. p- i.s.o. out error_msg. , , , p-, , error_msg.

MY_COMMAND_LIST = [ "<command that should go to background>" ]

def _popen( command_list, skip_com=False ):    
    p = subprocess.Popen( command_list, stdout=subprocess.PIPE,
        stderr=subprocess.PIPE )

    if not skip_com:
        out, error_msg = p.communicate()

        # Some processes (e.g. system_start) print a number of dots in stderr
        # even when no error occurs.
        if error_msg.strip('.') == '':
            error_msg = ''

        return out, error_msg
    else:
        return p

...
p = _popen( MY_COMMAND_LIST, True )
error = _get_command_pid( MY_COMMAND_LIST ) # checks if background command is running using _popen and ps -ef
if error:
    _, error_msg = p.communicate()

, .

stdout/stderr
2 , , script .
, , iter on, . p.stdout.readline. , :

for line in iter( p.stdout.readline, "" ): print line

- , ?

/edit/ , stdout stderr . stderr , , , , , , .

stdout , .

+4
2

,

, , DEVNULL .poll(), , .


, :

stdout = PIPE, stderr = PIPE, . , . >

- , . :

def process_output(process):
    with finishing(process): # close pipes, call .wait()
        for line in iter(process.stdout.readline, b''):
            if detected_error(line):
                communicate_error(process, line) 


process = Popen(command, stdout=PIPE, stderr=STDOUT, bufsize=1)
Thread(target=process_output, args=[process]).start()

, stdout stderr .

:

def read_stdout(process):
    with waiting(process), process.stdout: # close pipe, call .wait()
        for line in iter(process.stdout.readline, b''):
            do_something_with_stdout(line)

def read_stderr(process):
    with process.stderr:
        for line in iter(process.stderr.readline, b''):
            if detected_error(line):
                communicate_error(process, line) 

process = Popen(command, stdout=PIPE, stderr=PIPE, bufsize=1)
Thread(target=read_stdout, args=[process]).start()
Thread(target=read_stderr, args=[process]).start()

( do_something_with_stdout(), detected_error(), communicate_error()).

+1

, ...

, :

for line in p.stdout:
    #process line is you want of just
    print line

,

line = next(p.stdout)

, Python. C, stdout . , , (\n) . , , , kBytes. Python. , , , - ...

0

Source: https://habr.com/ru/post/1620355/


All Articles