일부 프로세스를 시작하고 이를 백그라운드로 보내는 실행 스크립트가 있습니다.
mongod & pid_mongo=$!
redis-server & pid_redis=$!
# etc.
그러면 이러한 모든 프로세스가 동시에 동일한 표준 출력으로 출력됩니다. 내 질문은: 서로 다른 분기 프로세스의 출력에 색상을 지정할 수 있습니까? 예를 들어 그 중 하나는 녹색으로 출력되고 다른 하나는 빨간색으로 출력됩니까?
답변1
red=$(tput setaf 1)
green=$(tput setaf 2)
default=$(tput sgr0)
cmd1 2>&1 | sed "s/.*/$red&$default/" &
cmd2 2>&1 | sed "s/.*/$green&$default/" &
답변2
필터를 통해 파이프를 연결하여 이를 수행할 수 있습니다. 각 줄 앞뒤에 적절한 ANSI 코드를 추가하면 됩니다.
http://en.wikipedia.org/wiki/ANSI_escape_sequences#Colors
몇 분 동안 인터넷 검색을 한 후에 실제로 이 작업을 수행하는 도구를 찾을 수 없었습니다. 작성하기가 얼마나 쉬운지를 고려하면 약간 이상합니다.
C를 사용한 아이디어는 다음과 같습니다.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
/* std=gnu99 required */
// ANSI reset sequence
#define RESET "\033[0m\n"
// length of RESET
#define RLEN 5
// size for read buffer
#define BUFSZ 16384
// max length of start sequence
#define START_MAX 12
void usage (const char *name) {
printf("Usage: %s [-1 N -2 N -b -e | -h]\n", name);
puts("-1 is the foreground color, -2 is the background.\n"
"'N' is one of the numbers below, corresponding to a color\n"
"(if your terminal is not using the standard palette, these may be different):\n"
"\t0 black\n"
"\t1 red\n"
"\t2 green\n"
"\t3 yellow\n"
"\t4 blue\n"
"\t5 magenta\n"
"\t6 cyan\n"
"\t7 white\n"
"-b sets the foreground to be brighter/bolder.\n"
"-e will print to standard error instead of standard out.\n"
"-h will print this message.\n"
);
exit (1);
}
// adds character in place and increments pointer
void appendChar (char **end, char c) {
*(*end) = c;
(*end)++;
}
int main (int argc, char *const argv[]) {
// no point in no arguments...
if (argc < 2) usage(argv[0]);
// process options
const char options[]="1:2:beh";
int opt,
set = 0,
output = STDOUT_FILENO;
char line[BUFSZ] = "\033[", // ANSI escape
*p = &line[2];
// loop thru options
while ((opt = getopt(argc, argv, options)) > 0) {
if (p - line > START_MAX) usage(argv[0]);
switch (opt) {
case '?': usage(argv[0]);
case '1': // foreground color
if (
optarg[1] != '\0'
|| optarg[0] < '0'
|| optarg[0] > '7'
) usage(argv[0]);
if (set) appendChar(&p, ';');
appendChar(&p, '3');
appendChar(&p, optarg[0]);
set = 1;
break;
case '2': // background color
if (
optarg[1] != '\0'
|| optarg[0] < '0'
|| optarg[0] > '7'
) usage(argv[0]);
if (set) appendChar(&p, ';');
appendChar(&p, '4');
appendChar(&p, optarg[0]);
set = 1;
break;
case 'b': // set bright/bold
if (set) appendChar(&p, ';');
appendChar(&p, '1');
set = 1;
break;
case 'e': // use stderr
output = STDERR_FILENO;
break;
case 'h': usage(argv[0]);
default: usage(argv[0]);
}
}
// finish 'start' sequence
appendChar(&p, 'm');
// main loop
// set non-block on input descriptor
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
// len of start sequence
const size_t slen = p - line,
// max length of data to read
rmax = BUFSZ - (slen + RLEN);
// actual amount of data read
ssize_t r;
// index of current position in output line
size_t cur = slen;
// read buffer
char buffer[rmax];
while ((r = read(STDIN_FILENO, buffer, rmax))) {
if (!r) break; // EOF
if (r < 1) {
if (errno == EAGAIN) continue;
break; // done, error
}
// loop thru input chunk byte by byte
// this is all fine for utf-8
for (int i = 0; i < r; i++) {
if (buffer[i] == '\n' || cur == rmax) {
// append reset sequence
for (int j = 0; j < RLEN; j++) line[j+cur] = RESET[j];
// write out start sequence + buffer + reset
write(output, line, cur+RLEN);
cur = slen;
} else line[cur++] = buffer[i];
}
}
// write out any buffered data
if (cur > slen) {
for (int j = 0; j < RLEN; j++) line[j+cur] = RESET[j];
write(output, line, cur+RLEN);
}
// flush
fsync(output);
// the end
return r;
}
나는 그것이 당신이 얻을만큼 효율적이라고 생각합니다. 전체 행은 write()
ANSI 시퀀스로 한 번에 완료되어야 합니다 . ANSI 시퀀스와 버퍼 내용이 별도로 완료되면 병렬 포크를 사용한 테스트에서 인터리빙이 발생할 수 있습니다.
C99 표준의 일부가 아니라 GNU의 일부이므로 -std=gnu99
컴파일 이 필요합니다 . getopt
나는 병렬 포크를 사용하여 이에 대해 몇 가지 테스트를 수행했습니다. 소스 코드, makefile 및 테스트는 여기 tarball에 있습니다.
http://cognitivedissonance.ca/cogware/utf8_colorize/utf8_colorize.tar.bz2
표준 오류에 기록하는 응용 프로그램과 함께 사용하는 경우 해당 응용 프로그램도 리디렉션해야 합니다.
application 2>&1 | utf8-colorize -1 2 &
테스트 디렉터리의 .sh 파일에는 몇 가지 사용 예가 포함되어 있습니다.
답변3
로그를 특정 출력 파일로 리디렉션하는 것이 더 나을 수 있습니까?
출력 색상을 지정하는 데는 다양한 솔루션이 있습니다. 가장 간단한 것은 아마도GRC팩..
답변4
sh 내장 함수와 함께 사용할 수 있는 또 다른 옵션: ash(busybox)에서도 작동합니다. ;)
RED=`echo -e '\033[0;31m'`
NC=`echo -e '\033[0m'` # No Color
cmdx 2>&1 | sed "s/.*/$RED&$NC/" &
백그라운드에서 프로그램을 쉽게 실행하기 위해 쉘 함수를 직접 작성했습니다. 이것은 비지박스의 잿더미를 위해 작성된 것입니다! bash에서도 작동합니다. 빨리 달려:
bg_red <whatever cmd you want to run in the bg>
.bashrc에 다음을 입력하세요.
ESC="\033"
# Colors:
COLOR_RED_F="${ESC}[31m"
COLOR_GREEN_F="${ESC}[32m"
COLOR_RESET="${ESC}[0m"
bg_red()
{
[ "$#" -lt "1" ] && echo "bg_red() <cmd to run in bg>" && return 1
PIPE_RED=`echo -e $COLOR_RED_F`
PIPE_NC=`echo -e $COLOR_RESET`
$@ 2>&1 | sed "s/.*/$PIPE_RED&$PIPE_NC/" &
}
여기에 표시된 대로: http://www.bramschoenmakers.nl/en/node/511.html