0

So I have a script that that sends requests to a website and then displays the status codes for the response packets. Something like:

METHOD | COUNT

  200  | 2 results
  404  | 987 results
  500  | 1 results
  ...

It takes a while to complete, so I've left it running on a box that I ssh into using the Linux tool Screen. The problem with this is screen doesn't work with Python's curses module, since to detach from the screen terminal (so I can log out and leave it running) it requires me to press ctrl+a+d which is captured and then ignored by curses.

I know you can overwrite single lines outputted to the console in Python like this:

    out = "200 | {} results\r".format(num)
    sys.stdout.write(out)
    sys.stdout.flush()

But is there a way to extend that to multiple lines so I can do something more like:

    # Updates approx once a second
    out = ""
    for code, num in STATUS_CODES:
        out += "{} | {}\r\n".format(code, num)

    sys.stdout.write(out)
    sys.stdout.flush()
Sam
  • 2,172
  • 3
  • 24
  • 43
  • You should be able to use `curses` just fine without it intercepting the CTRL+A, D sequence... – AKX May 23 '18 at 13:49
  • `curses` and the script itself run fine. The problem is, pressing `ctrl+a+d` doesn't do anything anymore after I switched to `curses` from `sys.stdout.write()` So I can't exit it at all without stopping the script from running. – Sam May 23 '18 at 13:55
  • How are you initializing `curses`? (To be clear, if I just do `import curses; w = curses.initscr()` within a `screen` session, I can still Ctrl+A, D just fine.) – AKX May 23 '18 at 13:57
  • With the wrapper around main: `curses.wrapper(main)` and then using the `stdscr` object that gets passed into `main` as a parameter. I guess I could try it with the `stdscr = curses.initscr()` instead and see if that helps – Sam May 23 '18 at 13:59
  • Right. `wrapper` does other things than just `initscr`, so they're probably the problem here. https://github.com/python/cpython/blob/825aab95fde959541859383f8ea7e7854ebfd49f/Lib/curses/__init__.py#L75-L83 – AKX May 23 '18 at 14:05
  • No luck with `stdscr = curses.initscr()`, unfortunately. I can `ctrl+c` to quit the script perfectly (though I'm explicitly handling that), but for some reason the `screen` signals, e.g. `ctrl+a+d` and `ctrl+a+k` don't register. – Sam May 23 '18 at 14:40

1 Answers1

0

The answer for me was to clear the entire screen with:

sys.stdout.write("\x1b[2J\x1b[H")

and then rewrite all my data at each update. Note that this is not ideal, since it apparently only works in ANSI supported terminals, and seems kinda hacky. Since my script is just for me though, it suited my purposes.

Sam
  • 2,172
  • 3
  • 24
  • 43