Можно ли позволить фоновому процессу непрерывно выводить на терминал?

Вот пример использования, чтобы прояснить мой вопрос. Скажем, у меня есть программа календаря, которая настроена на запуск в ~/.bashrc , и это гарантирует, что потоковый вывод перезаписывает один и тот же блок строк.

Возможно ли, чтобы потоковый вывод отображался в терминале из фонового процесса без слияния нового ввода? Я уже посмотрел на Отображение stdout фонового процесса в определенном месте терминала , но запрашивающий требует вывода новых строк при завершении, что мне не нужно делать.

Вот скриншот выхода программы, который в настоящее время выполняется на переднем плане и завершается после вывода форматированного текста один раз: Терминал после выхода программы

Я просто хочу, чтобы этот форматированный текст постоянно менял себя, позволяя процессам переднего плана функционировать нормально. Решение в Bash, C и / или C ++, используя что-то вроде escape-последовательностей zsh или ANSI, было бы идеально для меня.

Для справки, вот текущий код C, который я использую, но если вам это проще, вы можете просто сформулировать решение, которое использует cal :

 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> const char months[12][10] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; const char weekDays[7][10] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; void printCalendar(void); int getWeekDay(int, int, int, int, int); int getMaxDay(int, int); void getDate(int *, int *, int *, int *, int *, int *, int *); void formatTime(char *, int, int, int); int main(void) { printCalendar(); return 0; } void printCalendar(void) { int second, minute, hour, day, month, year, weekDay, maxDay, col, x = 0, i; char str[12]; getDate(&second, &minute, &hour, &day, &month, &year, &weekDay); formatTime(str, hour, minute, second); maxDay = getMaxDay(month, year); printf("\e[3J"); printf("%s %s\n", weekDays[weekDay], str); printf("%s %d, %d\n\n ", months[month], day, year); printf("Sun Mon Tue Wed Thu Fri Sat\n "); for (i = 1; i <= maxDay; i++) { col = getWeekDay(i, month, year, day, weekDay); if (x > col) { x = 0; printf("\n "); } while (x < col) { x++; printf(" "); } x++; if (i == day) { if (i < 10) { printf(" "); } printf(" \e[7m%d\e[0m ", i); } else { printf("%3d ", i); } } printf("\n\n"); } int getWeekDay(int day, int month, int year, int rmday, int rwday) { return (day - rmday + rwday + 35) % 7; } int getMaxDay(int month, int year) { switch (month) { case 3: // April case 5: // June case 8: // September case 10:// November return 30; case 1: // February if ((year % 100 == 0 && year % 400 != 0) || year % 4 != 0) { return 28; // Not leap year } return 29; // Leap year default: return 31; // Remaining months } } void getDate(int *second, int *minute, int *hour, int *day, int *month, int *year, int *weekDay) { time_t now; struct tm *date; time(&now); date = localtime(&now); *second = (date -> tm_sec); *minute = (date -> tm_min); *hour = (date -> tm_hour); *day = (date -> tm_mday); *month = (date -> tm_mon); *year = (date -> tm_year) + 1900; *weekDay = (date -> tm_wday); } void formatTime(char *str, int hour, int minute, int second) { sprintf(str, "%02d:%02d:%02d %s", (hour % 12) ? (hour % 12) : 12, minute, second, hour / 12 ? "PM" : "AM"); str[11] = '\0'; } 

И код в ~/.bashrc справедлив:

 clear && ~/Documents/C/Calendar/calendar 

Спасибо за любую помощь

2 Solutions collect form web for “Можно ли позволить фоновому процессу непрерывно выводить на терминал?”

Для этого я рекомендую screen GNU. Сначала запустите новый экземпляр screen :

 $ screen 

Затем сделайте разделение с помощью Ctrl + A Shift + S. Вы можете изменить размер верхней части с помощью команды resize . Я нашел высоту 9, чтобы быть разумным для cal :

Ctrl + A :resize 9

Затем используйте любую команду, которая постоянно производит вывод. Я не использую watch или даже не пользуюсь многими системами, но

 while true; do cal; sleep 3; done 

работает так же хорошо.

Затем Ctrl + A Tab перемещает вас к другой (нижней) части раскола. Наконец, Ctrl + A C открывает новую оболочку, в которой вы можете запускать команды без помех из другой части раскола.


Если вы хотите, чтобы это произошло автоматически, вы можете использовать .screenrc :

 screen /bin/sh -c 'while true; do cal; sleep 3; done' split resize 9 focus screen 

См. screen(1) для полного описания команд и возможного вдохновения для альтернативных конфигураций.

В принципе, да. Возможно иметь фоновое запущенное приложение, которое выводит что-то на stdout :

ping 8.8.8.8 &> /dev/stdout &

Так:

  • &> отправить stdout и stderr в stdout ,
  • & в конце делает ping работающий в фоновом режиме.

Но, насколько я понимаю ваш случай использования должным образом, лучшая идея будет заключаться в том, чтобы watch [ 1 ] на переднем плане. Он периодически выполняет команду, указанную в качестве аргумента, и представляет результаты ее выполнения.

Linux и Unix - лучшая ОС в мире.