I'm writing a Python app that runs a command on an AWS remote docker container, and saves the output to a file. The command that is being run remotely is generating binary data (a database dump).
The app works great if I start the download and don't touch anything. The issue I'm having is that if I start the download, and hit Enter while it's downloading, or scroll my mouse wheel in the terminal window, my output file gets a ^M, or weird characters.
Sample Code:
#!/usr/bin/env python3
import npyscreen
import curses
import subprocess
MY_REGION=...
MY_CLUSTER=...
MY_TASK=...
MY_CONTAINER=...
class ProgressForm(npyscreen.Popup):
def create(self):
self.progress = self.add(
npyscreen.TitleSliderPercent, step=1, out_of=100, name="Progress"
)
def activate(self):
cmd = subprocess.Popen(
[
"aws",
"--region",
MY_REGION,
"ecs",
"execute-command",
"--cluster",
MY_CLUSTER,
"--task",
MY_TASK,
"--container",
MY_CONTAINER,
"--command",
"python -c 'for i in range(500_000): print(i)'",
"--interactive",
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
bufsize=0,
)
total_size = 3889129
downloaded = 0
with open("out.log", "wb") as f:
while True:
chunk = cmd.stdout.read(1024)
if not chunk:
break
f.write(chunk)
downloaded += len(chunk)
self.progress.set_value(min(downloaded/total_size*100, 100))
self.progress.display()
self.parentApp.switchForm(None)
class MAIN(npyscreen.FormBaseNew):
def create(self):
self.items = self.add(
npyscreen.GridColTitles,
col_titles=["Column"],
select_whole_line=True,
)
self.items.add_handlers({curses.ascii.NL: self.item_chosen})
def activate(self):
for i in range(4):
self.items.values = [
["Row Data"]
]
self.edit()
def item_chosen(self, inpt):
self.parentApp.switchForm("progressForm")
class App(npyscreen.NPSAppManaged):
def onStart(self):
self.addForm("MAIN", MAIN, name="My App")
self.addForm("progressForm", ProgressForm)
if __name__ == "__main__":
app = App().run()
Hitting Enter during the download, or scrolling the mouse wheel results in this:
...
10667
10668
10669
...
and this:
...
17451
17452
17453
^[[<65;121;31M17454
17455
17456
17457
...
Why is my subprocess' stdout being littered with junk data?
Edit: The full output can be found here