Skip to content

Commit 0bc10b7

Browse files
committed
Fix run_command sometimes stops
1 parent c658112 commit 0bc10b7

File tree

1 file changed

+47
-44
lines changed

1 file changed

+47
-44
lines changed

adafruit_shell.py

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import os
2626
import shutil
2727
import subprocess
28+
import shlex
29+
import fcntl
2830
import platform
2931
import fileinput
3032
import re
@@ -67,75 +69,76 @@ def run_command(self, cmd, suppress_message=False, return_output=False):
6769
"""
6870
Run a shell command and show the output as it runs
6971
"""
70-
original_stdout = sys.stdout
71-
original_stderr = sys.stderr
72-
try:
73-
# pylint: disable=consider-using-with
74-
proc = subprocess.Popen(
75-
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
76-
)
77-
# pylint: enable=consider-using-with
78-
full_output = ""
79-
while True:
80-
output = proc.stdout.readline()
81-
err = proc.stderr.read()
82-
if err and not suppress_message:
83-
self.error(err.decode("utf-8", errors="ignore"))
84-
if len(output) == 0 and proc.poll() is not None:
85-
break
86-
if output:
87-
decoded_output = output.decode("utf-8", errors="ignore").strip()
88-
if not suppress_message:
89-
self.info(decoded_output)
90-
full_output += decoded_output
91-
except Exception: # pylint: disable=broad-except
92-
pass
93-
finally:
94-
sys.stdout = original_stdout
95-
sys.stderr = original_stderr
96-
if return_output:
97-
return full_output
98-
r = proc.poll()
99-
if r == 0:
72+
def non_block_read(output):
73+
fd = output.fileno()
74+
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
75+
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
76+
try:
77+
return output.read()
78+
except:
79+
return ""
80+
81+
full_output = ""
82+
with subprocess.Popen(
83+
cmd,
84+
shell=True,
85+
stdout=subprocess.PIPE,
86+
stderr=subprocess.PIPE,
87+
universal_newlines=True
88+
) as proc:
89+
while proc.poll() is None:
90+
err = non_block_read(proc.stderr)
91+
if err != "" and not suppress_message:
92+
self.error(err.strip(), end="\n\r")
93+
output = non_block_read(proc.stdout)
94+
if output != "" and not suppress_message:
95+
self.info(output.strip(), end="\n\r")
96+
full_output += output
97+
return_code = proc.poll()
98+
proc.stdout.close()
99+
proc.stderr.close()
100+
if return_output:
101+
return full_output
102+
if return_code:
103+
return False
100104
return True
101-
return False
102105

103-
def info(self, message):
106+
def info(self, message, **kwargs):
104107
"""
105108
Display a message with the group in green
106109
"""
107110
if self._group is not None:
108-
print(colored.green(self._group) + " " + message)
111+
print(colored.green(self._group) + " " + message, **kwargs)
109112
else:
110-
print(message)
113+
print(message, **kwargs)
111114

112-
def warn(self, message):
115+
def warn(self, message, **kwargs):
113116
"""
114117
Display a message with the group in yellow
115118
"""
116119
if self._group is not None:
117-
print(colored.yellow(self._group) + " " + message)
120+
print(colored.yellow(self._group) + " " + message, **kwargs)
118121
else:
119-
print(message)
122+
print(message, **kwargs)
120123

121-
def bail(self, message=None):
124+
def bail(self, message=None, **kwargs):
122125
"""
123126
Exit and display an error message if given
124127
"""
125128
if message is None:
126-
self.error("Exiting due to error")
129+
self.error("Exiting due to error", **kwargs)
127130
else:
128-
self.error(f"Exiting due to error: {message}")
131+
self.error(f"Exiting due to error: {message}", **kwargs)
129132
sys.exit(1)
130133

131-
def error(self, message):
134+
def error(self, message, **kwargs):
132135
"""
133-
Display some inforrmation
136+
Display some information
134137
"""
135138
if self._group is not None:
136-
print(colored.red(self._group) + " " + message)
139+
print(colored.red(self._group) + " " + message, **kwargs)
137140
else:
138-
print(message)
141+
print(message, **kwargs)
139142

140143
@staticmethod
141144
def print_colored(message, color):

0 commit comments

Comments
 (0)