Стереть весь вывод программы

Когда закрывается приложение написанное при помощи библиотеки на подобии ncurses (vim, mc, htop) - его вывод (интерфейс) пропадает и курсор приглашения ввода переходит на следующую строку (будто вывода и не было). Как это можно реализовать на Python без ncurses или подобных библиотек типа termbox, npyscreen и подобных?


Ответы (3 шт):

Автор решения: Интик

Чуток нето, но можно затирать строку после каждого вывода.

import time
for i in range(30):
    print(i, end='')
    print('\r', end='')
    time.sleep(0.1)

Весь вывод в 1 строчку.нет захламления консоли и нечего очищать.

→ Ссылка
Автор решения: eri

ncurses делает это через создание нового терминала

root@route:~# ls /dev/pts/
0  1  2  3  4  5  6  ptmx
root@route:~# mc

root@route:~# ls /dev/pts/
0  1  2  3  4  5  6  7  8  ptmx

7 - окошко, 8 - командная строка снизу

Как он это делает точно не знаю, но мне кажется через подмену дескриптора управляющего терминала.

→ Ссылка
Автор решения: MiniMax

1.

Как это можно реализовать на Python без ncurses или подобных библиотек?

Можно сделать также как ncurses - с помощью альтернативного буфера экрана The Alternate Screen Buffer.

Не все терминалы обладают данной функциональностью - например, виртуальный терминал (tty). Если запустите top или less в tty терминале, то увидете, что предыдущее содержимое экрана уходит вверх после запуска подобных программ. Узнать тип терминала можно с помощью команды echo $TERM.

Код для xterm-256color терминала:

from time import sleep

print("\033[?1049h", end='')         # Переключиться на альтернативные буфер экрана
print("\033[H", end='')              # Установить курсор в левый верхний угол

print("Alternate_screen_string_1")
print("Alternate_screen_string_2")
print("Alternate_screen_string_3")
print("Alternate_screen_string_4")
print("Alternate_screen_string_5")
print("Alternate_screen_string_6")

sleep(3)                             # Пауза нужна, чтобы успеть увидеть содержимое альтернативного буфера

print("\033[?1049l", end='')         # Переключиться на обычный буфер экрана

2.

Как работает ncurses программа можно посмотреть следующим образом:

2.1. Создаём минимальную программу c ncurses:

#include <ncurses.h>

int main()
{   
    napms(25000);               /* Пауза нужна, чтобы было время поймать процесс с помощью strace */
    initscr();
    printw("Hello World !!!");
    refresh();
    endwin();

    return 0;
}

2.2. Компилируем и запускаем:

gcc curses_hello_world.c -o curses_hello_world -lncurses

./curses_hello_world

2.3. Переходим в другой терминал и подключаемся к процессу curses_hello_world:

sudo strace -s 99 -p $(pgrep curses_hello_wo) 2>&1 | less

2.4. Ждём 25 секунд и получаем системные вызовы, которые делала наша программа во время работы. В данном случае нас интересует системные вызовы write:

write(1, "\33[?1049h\33[22;0;0t\33[1;39r\33(B\33[m\33[4l\33[?7h\33[H\33[2J", 46) = 46
write(1, "Hello World !!!", 15)         = 15
write(1, "\33[39;1H\33[?1049l\33[23;0;0t\r\33[?1l\33>", 32) = 32

С расшифровкой этих эскейп последовательностей мне помогли здесь (на английском).

→ Ссылка