É possível permitir que um processo em background seja continuamente enviado para o terminal?

5

Aqui está um caso de uso para esclarecer minha dúvida. Digamos que eu tenha um programa de calendário que esteja configurado para ser executado em ~/.bashrc e garanta que a saída de streaming substitua o mesmo bloco de linhas.

É possível exibir a saída de streaming no terminal a partir do processo em segundo plano sem afetar a nova entrada? Eu já olhei para Exibindo o stdout de um processo em segundo plano na localização específica do terminal , mas o consulente requer a geração de novas linhas na terminação, o que eu não preciso fazer.

Aqui está uma captura de tela da saída do programa, que atualmente é executada em primeiro plano e termina após a saída do texto formatado uma vez:

Eusóqueroqueotextoformatadoparasubstituircontinuamentesepermitindoqueosprocessosemprimeiroplanofuncionemcomonormal.UmasoluçãonoBash,Ce/ouC++usandoalgocomozshouseqüênciasdeescapeANSIseriaperfeitaparamim.

Parareferência,aquiestáocódigoCatualqueestouusando,masseformaisfácilparavocê,vocêpodeapenasformularumasoluçãoqueusecal:

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<time.h>constcharmonths[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] = '
clear && ~/Documents/C/Calendar/calendar
'; }

E o código em ~/.bashrc é apenas:

#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] = '
clear && ~/Documents/C/Calendar/calendar
'; }

Obrigado por qualquer ajuda

    
por Patrick Roberts 05.05.2017 / 23:36

2 respostas

7

Eu recomendo o GNU screen para isso. Primeiro, inicie uma nova instância screen :

$ screen

Em seguida, faça uma divisão com Ctrl + A Deslocamento + S . Você pode redimensionar a parte superior com o comando resize . Eu achei uma altura de 9 para ser razoável para cal :

Ctrl + A :resize 9

Em seguida, use qualquer comando que produza saída constantemente. Eu não uso watch ou até mesmo em muitos sistemas, mas

while true; do cal; sleep 3; done

funciona igualmente bem.

Então Ctrl + Uma Aba move você para a outra parte (inferior) da divisão. Finalmente, Ctrl + A C abre um novo shell no qual você pode executar comandos sem interferência da outra parte da divisão.

Se você deseja que isso ocorra automaticamente, use .screenrc :

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

Veja screen(1) para uma descrição completa dos comandos e possível inspiração para configurações alternativas.

    
por 06.05.2017 / 00:19
0

Basicamente, sim. É possível ter um aplicativo em execução em segundo plano que produza algo em stdout :

ping 8.8.8.8 &> /dev/stdout &

Então:

  • &> enviar stdout e stderr para stdout ,
  • & no final faz com que ping funcione em segundo plano.

Mas, até onde eu entendi seu caso de uso corretamente, a melhor idéia será ter watch [ 1 ] aplicativo em primeiro plano. Ele executa periodicamente um comando que é especificado como um argumento e apresenta seus resultados de execução.

    
por 06.05.2017 / 00:00