Я хочу написать программу на linux, которая постоянно обновляет экран и обновляет его в режиме реального времени (например, аналогично команде top
в терминале). Может ли кто-нибудь указать мне в правильном направлении.
Как постоянно обновлять экран и обновлять его в режиме реального времени
Ответ 1
Чтобы переносить его по типам терминалов, вам необходимо использовать библиотеку, такую как ncurses. Проверьте эту ссылку, ее исчерпывающий учебник.
Вот базовая программа, которая печатает все большее число в левом верхнем углу экрана:
#include <stdio.h>
#include <ncurses.h>
int main (void)
{
/* compile with gcc -lncurses file.c */
int c = 0;
/* Init ncurses mode */
initscr ();
/* Hide cursor */
curs_set (0);
while (c < 1000) {
/* Print at row 0, col 0 */
mvprintw (0, 0, "%d", c++);
refresh ();
sleep (1);
}
/* End ncurses mode */
endwin();
return 0;
}
Вот как вы обновляете окно. Теперь, если вы хотите отображать строки данных как top
, то отображаемые данные должны поддерживаться в упорядоченной структуре данных (в зависимости от ваших данных это может быть нечто простое, как массив или связанный список). Вам придется сортировать данные на основе того, что ваша логика диктует и переписывает в окно (как показано в примере выше) после clear()
или wclear()
.
Ответ 2
Некреты могут быть путем. Поскольку вы сказали программу, то ncurses, c, С++. Посмотрите на все это. Но если вы планируете делать что-то вроде "shelL", переходите к perl.
Изменить: Чтобы добавить к моей точке, вот некоторые модули, которые могут дать вам идею.
http://metacpan.org/pod/Curses::UI::Dialog::Progress
http://metacpan.org/pod/Smart::Comments
window.clrtobot()
И для хорошей меры - вызов проклятий, чтобы очистить все окно.
Ответ 3
Если вы находитесь под xterm
или VT100
совместимыми, вы можете использовать коды консоли, например:
#include <stdio.h>
#include <unistd.h> /* for sleep */
#define update() printf("\033[H\033[J")
#define gotoxy(x, y) printf("\033[%d;%dH", x, y)
int main(void)
{
update();
puts("Hello");
puts("Line 2");
sleep(2);
gotoxy(0, 0);
puts("Line 1");
sleep(2);
return(0);
}
Вы можете делать почти все с escape-последовательностями, но как указано в wikipedia: ncurses
оптимизирует изменения экрана, чтобы уменьшить задержка, возникающая при использовании удаленных оболочек.
Ответ 4
В зависимости от вашей ситуации вы можете использовать команду "смотреть" в командной строке, чтобы получить быстрые виды, такие как верх. Вы также можете просматривать несколько команд одновременно.
Пример:
watch 'ls -l <somefile>; ps -fC <someprocess>; ./some_script'
Ответ 5
Также, используя библиотеку ncurses для обработки экрана, если вы хотите обновить ее "постоянно" и "в режиме реального времени", вам, вероятно, захочется также заглянуть в таймеры и обработку сигналов. timer_create()
и timer_settime()
могут получить таймер, а затем вы можете использовать sigaction()
, чтобы установить функцию обработчика, чтобы захватить сигнал SIGALRM
и выполнить обновление.
ИЗМЕНИТЬ: Вот пример кода, запрошенный:
#define TIMESTEP 200000000
timer_t SetTimer(void) {
struct itimerspec new_its;
struct sigevent sevp;
timer_t main_timer;
sevp.sigev_notify = SIGEV_SIGNAL;
sevp.sigev_signo = SIGALRM;
timer_create(CLOCK_REALTIME, &sevp, &main_timer);
new_its.it_interval.tv_sec = 0;
new_its.it_interval.tv_nsec = TIMESTEP;
new_its.it_value.tv_sec = 0;
new_its.it_value.tv_nsec = TIMESTEP;
timer_settime(main_timer, 0, &new_its, NULL);
return main_timer;
}
void SetSignals(void) {
struct sigaction sa;
/* Fill in sigaction struct */
sa.sa_handler = handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
/* Set signal handler */
sigaction(SIGALRM, &sa, NULL);
}
void handler(int signum) {
switch (signum) {
case SIGALRM:
update_stuff(); /* Do your updating here */
break;
}
}
Ответ 6
Как говорили другие, вы, вероятно, захотите посмотреть библиотеку ncurses. Но если вам не требуется расширенное форматирование, возможно, чего-то такого простого может быть достаточно:
#include <stdio.h>
#include <unistd.h>
int main(void) {
int number = 0;
while (1) {
++number;
printf("\rThe number is now %d.", number);
fflush(stdout);
sleep(1);
}
return 0;
}