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

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

какие-либо практические примеры?

спасибо.

5 ответов


одним из примеров использования будет перенаправление ввода-вывода. Для этого вы разветвляете дочерний процесс и закрываете файловые дескрипторы stdin или stdout (0 и 1), а затем выполняете dup() на другом выбранном вами filedescriptor, который теперь будет сопоставлен с самым низким доступным файловым дескриптором, который в данном случае 0 или 1.

используя это, вы можете выполнить любой дочерний процесс, который, возможно, не знает о вашем приложении и всякий раз, когда ребенок пишет на stdout (или читает из stdin, независимо от того, что вы настроено) вместо этого данные записываются на предоставленный filedescriptor.

оболочки используют это для реализации команд с каналами, например /bin/ls | more путем подключения stdout одного процесса к stdin другого.


лучший сценарий для понимания dup и dup2-перенаправление.
Первое, что нам нужно знать, - это то, что система имеет 3 идентификатора файлов по умолчанию(или переменные, указывающие выходные или входные источники), которые имеют дело с входом и выходом. Они stdin, stdout, stderr, в целых числах они 0,1,2. Большинство функций, таких как fprintf или cout непосредственно выводятся на stdout.
Если мы хотим перенаправить вывод, один из способов-дать, например, fprintf функция больше аргументов, указывающих in и out.
Однако есть более элегантный способ: мы можем перезаписать идентификаторы файлов по умолчанию, чтобы они указывали на файл, который мы хотим получить. dup и dup2 именно в этой ситуации.
Давайте начнем с одного простого примера: предположим, мы хотим перенаправить вывод fprintf в txt-файл с именем " chinaisbetter.формат txt." Прежде всего нам нужно открыть этот файл

int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);

затем мы хотим stdout чтобы указать на " chinaisbetter.txt " с помощью функции dup:

dup2(fw,1);

теперь stdout (1) указывает на дескриптор "chinaisbetter.txt", хотя это все еще 1, но вывод перенаправляется сейчас.
Тогда вы можете использовать printf как обычно, но результаты будут в txt-файле, а не отображаться непосредственно на экране:

printf("Are you kidding me? \n");

PS:

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

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


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

в этом случае:

следующие разделы являются информативными.

примеры

перенаправление стандартного вывода в файл

в следующий пример закрывает стандартный вывод для текущих процессов, повторно назначает стандартный вывод для перехода к файлу, на который ссылается pfd и закрывает исходный файловый дескриптор для очистки.

#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...

Перенаправление Сообщений Об Ошибках

следующий пример перенаправляет сообщения из stderr to stdout.

#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...

Использование Приложения

нет.

обоснование

на 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 .Я. e эмулирует поведение $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