Запись в файл stdout и файл

У меня есть родительский процесс, который выдает дочерний элемент для выполнения execv ().

Мне нужен вывод, выданный execv (), на stdout, который будет отображаться на экране, также скопированный в файл журнала.

Как написать тот же вывод в файл stdout и файл, не используя трубы или тройники ?

Если вы не хотите использовать тройник, прежде чем писать данные, напишите его в файл, а затем отправьте его в стандартный вывод.

Вы должны написать функцию регистрации, которая сделает это для вас, чтобы сделать его более чистым.

Протрите его через тройник .

Вы можете использовать dup2() – эта ссылка дает пример

Вы можете сделать это полностью в своей программе, но вам все равно придется использовать анонимные каналы, созданные системным вызовом pipe() .

В принципе, вам понадобится subprocess, который выполняет эквивалент tee , что довольно просто:

 int child_pipe[2]; pid_t pid_exec_child, pid_output_child; pipe(child_pipe); pid_exec_child = fork(); if (pid_exec_child == 0) { dup2(child_pipe[1], STDOUT_FILENO); close(child_pipe[0]); close(child_pipe[1]); execve(/* ... */); _exit(127); } close(child_pipe[1]); pid_output_child = fork(); if (pid_output_child == 0) { /* This child just loops around, reading from the other child and writing everything * to both stdout and the log file. */ int logfd = open("logfile", O_WRONLY); char buffer[4096]; ssize_t nread; while ((nread = read(child_pipe[0], buffer, sizeof buffer) != 0) { size_t nwritten_total; ssize_t nwritten; if (nread < 0) { if (errno == EINTR) continue; perror("read"); _exit(1); } /* Copy data to stdout */ nwritten_total = 0; while (nwritten_total < nread) { nwritten = write(STDOUT_FILENO, buffer + nwritten_total, nread - nwritten_total); if (nwritten < 0) { if (errno == EINTR) continue; perror("write(stdout)"); _exit(2); } nwritten_total += nwritten; } /* Copy data to logfile */ nwritten_total = 0; while (nwritten_total < nread) { nwritten = write(logfd, buffer + nwritten_total, nread - nwritten_total); if (nwritten < 0) { if (errno == EINTR) continue; perror("write(logfile)"); _exit(3); } nwritten_total += nwritten; } } _exit(0); } close(child_pipe[0]); /* Parent continues here */ 

Конечно, проще всего просто запустить tee у этого второго ребенка ...

(Обратите внимание, что дочерние процессы используют _exit() , поскольку они унаследовали стандартное состояние ввода-вывода от родителя).

Кроме того, вы можете использовать fifo. mkfifo my.fifo; в execv: program> my.fifo; и откройте fifo как обычный файл, читая его. Таким образом, вы можете проанализировать ваш stdout, но он имеет небольшие недостатки с общим доступом.

Вы хотите, чтобы только выход дочернего элемента поступал в журнал?

Команда tee unix выполняет именно то, что вы описываете: вы обрабатываете данные и записываете в журнал и в стандартный вывод.

Используйте Tee следующим образом:

 ./myprog | tee outputfile