практические примеры использования dup или dup2


Я знаю dup/dup2 делает, но я понятия не имею, когда он будет использоваться.

есть практические примеры?

спасибо.

5 58

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:

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

  2. идентификатор файла здесь относится к обработчику файла. Файловый дескриптор, упомянутый выше, является структурой информации файла записей.

когда вы интересуетесь функциями 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