백그라운드 프로세스가 터미널에 계속 출력되도록 할 수 있습니까?

백그라운드 프로세스가 터미널에 계속 출력되도록 할 수 있습니까?

내 질문을 명확히하기위한 사용 사례는 다음과 같습니다. ~/.bashrc스트림 출력이 동일한 행 블록을 포함하도록 보장하는 달력 프로그램이 에서 실행되도록 설정되어 있다고 가정해 보겠습니다.

새로운 입력을 파괴하지 않고 백그라운드 프로세스에서 터미널의 스트림 출력을 표시할 수 있습니까? 나는 이미 그것을 보았다터미널의 특정 위치에 백그라운드 프로세스의 표준 출력을 표시합니다., 그러나 질문자는 종료 시 개행 문자가 출력되도록 요청했는데, 저는 그럴 필요가 없습니다.

다음은 현재 포그라운드에서 실행 중이며 서식 있는 텍스트를 한 번 출력한 후 종료되는 프로그램 출력의 스크린샷입니다. 프로그램 출력 후 터미널

포그라운드 프로세스가 정상적으로 실행되도록 하면서 서식이 지정된 텍스트가 계속 교체되기를 원합니다. Bash, C 및/또는 C++에서 ANSI 이스케이프 시퀀스와 같은 것을 사용하는 솔루션이 zsh나에게 완벽할 것입니다.

참고로 제가 현재 사용하고 있는 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

당신의 도움에 감사드립니다

답변1

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)명령에 대한 전체 설명과 대체 구성에 대한 가능한 영감을 보려면 리소스를 참조하세요 .

답변2

기본적으로 그렇습니다. 백그라운드에서 무언가를 출력하는 애플리케이션이 실행될 수 있습니다 stdout.

ping 8.8.8.8 &> /dev/stdout &

그래서:

  • &>stdout로 보내기 ,stderrstdout
  • &ping마지막으로 백그라운드에서 작동하게 만듭니다 .

그러나 귀하의 사용 사례를 올바르게 이해하는 한 더 나은 아이디어는 watch[1] 애플리케이션이 포그라운드에 있습니다. 인수로 지정된 명령을 주기적으로 실행하고 실행 결과를 표시합니다.

관련 정보