def _persist(self):
<EOL>for command in self.commands:<EOL><INDENT>try:<EOL><INDENT>process = Popen(<EOL>[command],<EOL>stdout=PIPE,<EOL>stderr=PIPE,<EOL>universal_newlines=True,<EOL>env=self.env,<EOL>shell=True,<EOL>)<EOL><DEDENT>except Exception as e:<EOL><INDENT>retcode = process.poll()<EOL>msg = "<STR_LIT>"<EOL>self.py3.log(msg.format(cmd=command, error=e, retcode=retcode))<EOL><DEDENT>fd = process.stdout.fileno()<EOL>fl = fcntl.fcntl(fd, fcntl.F_GETFL)<EOL>has_newlines = False<EOL>while True:<EOL><INDENT>line = process.stdout.read(<NUM_LIT:1>)<EOL>fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)<EOL>line += process.stdout.read(<NUM_LIT>)<EOL>fcntl.fcntl(fd, fcntl.F_SETFL, fl)<EOL>if process.poll():<EOL><INDENT>break<EOL><DEDENT>if self.py3.is_python_2():<EOL><INDENT>line = line.decode("<STR_LIT:utf-8>")<EOL><DEDENT>self.persistent_output = line<EOL>self.py3.update()<EOL>if line[-<NUM_LIT:1>] == "<STR_LIT:\n>":<EOL><INDENT>has_newlines = True<EOL>break<EOL><DEDENT>if line == "<STR_LIT>":<EOL><INDENT>break<EOL><DEDENT><DEDENT>if has_newlines:<EOL><INDENT>msg = "<STR_LIT>"<EOL>self.py3.log(msg.format(cmd=command))<EOL>for line in iter(process.stdout.readline, b"<STR_LIT>"):<EOL><INDENT>if process.poll():<EOL><INDENT>break<EOL><DEDENT>if self.py3.is_python_2():<EOL><INDENT>line = line.decode("<STR_LIT:utf-8>")<EOL><DEDENT>self.persistent_output = line<EOL>self.py3.update()<EOL><DEDENT><DEDENT><DEDENT>self.py3.log("<STR_LIT>".format(cmd=command))<EOL>self.persistent_output = "<STR_LIT>".format(<EOL>self.py3.COLOR_ERROR or self.py3.COLOR_BAD<EOL>)<EOL>self.py3.update()<EOL>
Run the command inside a thread so that we can catch output for each
line as it comes in and display it.