Окраска вывода разветвленных процессов

Нет, я думаю, что нет.

Необходимо ли действительно зашифровать начальную загрузку/? Я подозреваю нет. Остальная часть файловой системы может быть зашифрована нормальным программным обеспечением Linux, которое находится на initramfs в начальной загрузке / и предлагает пользователю соответственно.

7
14.12.2012, 18:21
4 ответа

Вы могли сделать это путем передачи по каналу через фильтр, это - просто вопрос добавления соответствующих кодов 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 и содержимое буфера были сделаны отдельно.

Это должно быть скомпилировано -std=gnu99 с тех пор getopt не часть стандарта C99, но это - часть GNU. Я протестировал это несколько с параллельными ветвлениями; тот источник, make-файл и тесты находятся в tarball здесь:

http://cognitivedissonance.ca/cogware/utf8_colorize/utf8_colorize.tar.bz2

Если приложение, Вы используете это с журналами к стандартной погрешности, не забывают перенаправлять это также:

application 2>&1 | utf8-colorize -1 2 &

.sh файлы в тестовом каталоге содержат некоторые примеры использования.

2
27.01.2020, 20:18
  • 1
    Хотите объяснить немного далее (я - настоящий новичок в ударе)? Я должен добавить в инструкции по передаче по каналу прежде или после разветвления? –  user2398029 14.12.2012, 19:14
  • 2
    Прежде, т.е. mongod | colorfilter & pid_mongo=$! –  goldilocks 14.12.2012, 19:22
  • 3
    я решил лентяйничать немного и кодировать что-то для этого в C, поэтому если Вы не можете найти ничто больше, возвращается позже сегодня или завтра и я выставлю источник ссылки/некоторой для этого. Действительно должен быть простой, скомпилированный инструмент для этого. –  goldilocks 14.12.2012, 19:32
  • 4
    Потрясающий. Я буду видеть то, что я могу сделать на своей стороне и надеяться сравнить это с Вашим взятием на нем. –  user2398029 14.12.2012, 19:50
  • 5
    @louism: хорошо, я добавил некоторый код, и ссылка на Перенаправление tarball –  goldilocks 16.12.2012, 20:50
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/" &
5
27.01.2020, 20:18
  • 1
    +1 Для тестирования определите, например. cmd1() { while true; do echo foo; sleep 1; done } и cmd2() { while true; do echo bar; sleep 3; done } –  l0b0 17.12.2012, 15:02

Вы, вероятно, лучше из перенаправления журналов к определенным выходным файлам?

Существует много различных решений для вывода колоризации. Самое легкое, вероятно, должно было бы использовать grc пакет..

0
27.01.2020, 20:18
  • 1
    для разделения файлов не является наилучшим вариантом, если a) Вы пытаетесь наблюдать/отлаживать что-то в режиме реального времени. b) Вы хотите порядок событий от нескольких процессов, сохраненных, не имея необходимость сравнивать метки времени в отдельных файлах. Я предположил бы, что OP тестирует сервер фронтэнда, объединенный с сервером базы данных бэкенда (монго), и хочет видеть то, что происходит когда. –  goldilocks 16.12.2012, 21:13

другой вариант, который вы можете использовать со встроенной функцией sh: работает также и с ash (busybox);)

RED=`echo -e '\033[0;31m'`
NC=`echo -e '\033[0m'` # No Color

cmdx 2>&1 | sed "s/.*/$RED&$NC/" &

Я написал себе функцию оболочки, чтобы легко запускать программы в фоновом режиме. Это написано для пепла Busybox! Также работает в 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

0
27.01.2020, 20:18

Теги

Похожие вопросы