Command-Line

是否可以允許後台程序連續輸出到終端?

  • May 5, 2017

這是一個案例來澄清我的問題。假設我有一個設置為執行的日曆程序,~/.bashrc它確保流輸出覆蓋相同的行塊。

是否可以在不破壞新輸入的情況下從後台程序在終端中顯示流輸出?我已經看過Displaying stdout of a background process in the specific location of the terminal,但是詢問者需要在終止時輸出新行,我不需要這樣做。

這是程序輸出的截圖,它目前在前台執行,並在輸出一次格式化文本後終止: 程序輸出後的終端

我只是希望格式化的文本能夠不斷地替換自身,同時允許前台程序正常執行。在 Bash、C 和/或 C++ 中使用類似zshANSI 轉義序列的解決方案對我來說是完美的。

作為參考,這是我正在使用的目前 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

謝謝你的幫助

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打開一個新的 shell,您可以在其中執行命令,而不會受到拆分其他部分的干擾。


如果您希望這自動發生,您可以使用.screenrc

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

有關screen(1)命令的完整描述,以及替代配置的可能靈感,請參見 參考資料。

引用自:https://unix.stackexchange.com/questions/363311