принуждение программы сбросить ее стандартный вывод при перенаправлении

у меня есть программа с закрытым исходным кодом, которая печатает вывод к стандартному выводу. я должен проанализировать вывод. таким образом, я перенаправляю вывод к FIFO (из которого я могу читать в родительском процессе что ветвления и должностные лица двоичный файл), использующий dup2 и затем должностное лицо программа. проблема состоит в том, что вызовы fprintf в файле становятся буферизированными, потому что он теперь пишет в файл.

я пытался назвать setvbuf с _IONBF на stdout перед звонящим должностным лицом. но проблема все еще существует.

почему setvbuf не помогает в моем случае?

как я могу вынудить вывод быть сброшенным?

10
задан Rohit Banga 13 January 2010 в 10:23
поделиться

2 ответа

setvbuf() не имеет значения, так как изменяет состояние части библиотеки времени исполнения С, а не части ОС. Когда новый процесс начнет выполняться, его библиотека времени исполнения на С будет заново инициализирована (то есть, если она вообще использует CRT!)

Единственный способ обойти это - как-то подделать терминал под процесс. Это потому, что большинство библиотек CRT по умолчанию будут выполнять только буферизацию строк, если они считают, что прикреплены к интерактивному терминалу (в мире Unix: если isatty() возвращает true в файловом дескрипторе), в то время как в противном случае они будут буферизованы большими блоками (обычно 8Кб или около того).

Эта утилита выглядит довольно неплохим местом для начала. (Заимствованная из комментария к Хитрость приложения заключается в том, чтобы думать, что его stdin интерактивен, а не труба , в которой есть другая полезная информация)

.
6
ответ дан 4 December 2019 в 01:31
поделиться
-

Я думаю, у вас есть что-то подобное в вашей программе (вы можете воспроизвести это для своих тестов, я звоню в это Isatty здесь)

#include <stdio.h>
#include <unistd.h>

const char* m1 = "%d: %s a TTY\n";

void isTty(FILE* f) {
    int fno = fileno(f);
    printf(m1, fno, (isatty(fno)) ? "is" : "is NOT");
}

int main(int argc, char* argv[]) {
    isTty(stdin);
    isTty(stdout);
}

Например, если вы Запустите его

$ ./isatty
0: is a TTY
1: is a TTY

$ ./isatty > isatty.out
$ cat isatty.out 
0: is a TTY
1: is NOT a TTY

$ ./isatty > isatty.out < /dev/null
$ cat isatty.out 
0: is NOT a TTY
1: is NOT a TTY

Теперь, если вы создадите ожидаемый Script isatty.expect (установка ожидается для вашего дистрибутива, если не установлено)

#! /usr/bin/expect -f

spawn "./isatty"
expect

и запустить его

$ ./isatty.expect 
spawn ./isatty
0: is a TTY
1: is a TTY

или

$ ./isatty.expect > isatty.out 
$ cat isatty.out 
spawn ./isatty
0: is a TTY
1: is a TTY
2
ответ дан 4 December 2019 в 01:31
поделиться
Другие вопросы по тегам:

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