практические примеры использования dup или dup2
Я знаю dup/dup2 делает, но я понятия не имею, когда он будет использоваться.
есть практические примеры?
спасибо.
5 ответов:
одним из примеров использования будет перенаправление ввода-вывода. Для этого вы разветвляете дочерний процесс и закрываете файловые дескрипторы stdin или stdout (0 и 1), а затем выполняете dup() на другом выбранном вами файловом дескрипторе, который теперь будет сопоставлен с самым низким доступным файловым дескриптором, который в этом случае равен 0 или 1.
используя это, теперь вы можете выполнить любой дочерний процесс, который, возможно, не знает о вашем приложении и всякий раз, когда ребенок пишет на stdout (или читает из stdin, независимо от того, что вы настроено) вместо этого данные записываются на предоставленный filedescriptor.
оболочки используют это для реализации команд с трубами, например
/bin/ls | moreпри подключении стандартного вывода одного процесса на поток ввода другого.
лучший сценарий для понимания dup и dup2-это перенаправление.
Первое, что нам нужно знать, это то, что система имеет 3 идентификатора файлов по умолчанию(или переменные, указывающие источники вывода или ввода), которые имеют дело с вводом и выводом. Ониstdin,stdout,stderr, в целых числах они0,1,2. Большинство функций, таких какfprintfилиcoutнепосредственно выводятся наstdout.
Если мы хотим перенаправить вывод, один из способов-дать, например,fprintfфункция дополнительные аргументы, указывающиеinиout.
Однако есть более элегантный способ: мы можем перезаписать идентификаторы файлов по умолчанию, чтобы они указывали на файл, который мы хотим получить на выходе.dupиdup2именно в этой ситуации.
Давайте начнем с одного простого примера: предположим, что мы хотим перенаправить выводfprintfв текстовый файл с именем " chinaisbetter.формат txt." Прежде всего нам нужно открыть этот файлint fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);затем мы хотим
stdoutчтобы указать на " chinaisbetter.txt " с помощью функции dup:Тогда вы можете использоватьdup2(fw,1);printfкак обычно, но результаты будут в файле txt вместо того, чтобы показывать непосредственно на экране:printf("Are you kidding me? \n");PS:
это просто дает интуитивное объяснение, вам может понадобиться, чтобы проверить страница руководства или подробная информация. На самом деле, мы говорим "копировать" здесь, они не копируют все.
идентификатор файла здесь относится к обработчику файла. Файловый дескриптор, упомянутый выше, является структурой информации файла записей.
когда вы интересуетесь функциями POSIX, особенно теми, которые, похоже, дублируют себя, обычно хорошо проверьте сам стандарт. Внизу вы обычно увидите примеры, а также рассуждения о реализации (и существовании) обоих.
в этом случае:
следующие разделы являются информативными.
примеры
перенаправление стандартного вывода в файл
в следующий пример закрывает стандартный вывод для текущих процессов, повторно назначает стандартный вывод для перехода к файлу, на который ссылается
pfd, и закрывает исходный файловый дескриптор для очистки.#include <unistd.h> ... int pfd; ... close(1); dup(pfd); close(pfd); ...Перенаправление Сообщений Об Ошибках
в следующем примере перенаправляются сообщения из
stderrдоstdout.#include <unistd.h> ... dup2(2, 1); // 2-stderr; 1-stdout ...Использование Приложения
нет.
обоснование
The
dup()иdup2()функции избыточный. Их услуги также предоставляются
одним из практических примеров является перенаправление выходных сообщений в какой-либо другой поток, например в файл журнала. Вот пример кода для перенаправления ввода-вывода.
Пожалуйста, обратитесь к оригинальному сообщению здесь#include <stdio.h> main() { int fd; fpos_t pos; printf("stdout, "); fflush(stdout); fgetpos(stdout, &pos); fd = dup(fileno(stdout)); freopen("stdout.out", "w", stdout); f(); fflush(stdout); dup2(fd, fileno(stdout)); close(fd); clearerr(stdout); fsetpos(stdout, &pos); /* for C9X */ printf("stdout again\n"); } f() { printf("stdout in f()"); }
перенаправление ввода-вывода в оболочке, скорее всего, будет реализовано с помощью системных вызовов dup2/fcnlt.
мы можем легко подражать
$program 2>&1 > logfile.logтип перенаправления с помощью функции dup2.программа ниже перенаправляет как stdout, так и stderr .т. е. эмулирует поведение
$program 2>&1 > outputС помощью dup2.#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> int main(void){ int close_this_fd; dup2(close_this_fd = open("output", O_WRONLY), 1); dup2(1,2); close(close_this_fd); fprintf(stdout, "standard output\n"); fprintf(stderr, "standard error\n"); fflush(stdout); sleep(100); //sleep to examine the filedes in /proc/pid/fd level. return; } vagrant@precise64:/vagrant/advC$ ./a.out ^Z [2]+ Stopped ./a.out vagrant@precise64:/vagrant/advC$ cat output standard error standard output vagrant@precise64:/vagrant/advC$ ll /proc/2761/fd total 0 dr-x------ 2 vagrant vagrant 0 Jun 20 22:07 ./ dr-xr-xr-x 8 vagrant vagrant 0 Jun 20 22:07 ../ lrwx------ 1 vagrant vagrant 64 Jun 20 22:07 0 -> /dev/pts/0 l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 1 -> /vagrant/advC/output l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 2 -> /vagrant/advC/output