これが私の質問を明確にするためのユースケースです。 ~/.bashrc
で実行するように設定されたカレンダープログラムがあり、ストリーミング出力が同じ行ブロックを上書きすることを保証するとします。
新しい入力を壊すことなく、バックグラウンドプロセスから端末にストリーミング出力を表示することは可能ですか?すでに 端末の特定の場所にバックグラウンドプロセスのstdoutを表示する を見ましたが、askerは終了時に新しい行を出力する必要があります。
これは、現在フォアグラウンドで実行され、フォーマットされたテキストを1回出力した後に終了するプログラム出力のスクリーンショットです。
フォアグラウンドプロセスが通常どおり機能するようにしながら、フォーマットされたテキストを継続的に置き換えたいだけです。 zsh
またはANSIエスケープシーケンスのようなものを使用したBash、C、および/またはC++のソリューションは私にとって完璧です。
参考までに、現在使用している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
助けてくれてありがとう
これにはGNU screen
をお勧めします。まず、新しいscreen
インスタンスを起動します。
_$ screen
_
次に、で分割します Ctrl+AShift+S。 resize
コマンドを使用して、上部のサイズを変更できます。 cal
の高さは9が妥当であることがわかりました。
Ctrl+A _:resize 9
_
次に、常に出力を生成するコマンドを使用します。私はwatch
を使用していないか、多くのシステムで使用していますが、
_while true; do cal; sleep 3; done
_
同様に機能します。
次に Ctrl+ATab 分割の他の(下部)部分に移動します。最後に、 Ctrl+AC 分割の他の部分からの干渉なしにコマンドを実行できる新しいシェルを開きます。
これを自動的に発生させたい場合は、_.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 ]アプリケーションをフォアグラウンドに置くことをお勧めします。引数として指定されたコマンドを定期的に実行し、実行結果を表示します。