практические примеры использования 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:
это просто дает интуитивное объяснение, вам может понадобиться, чтобы проверить manpage или подробная информация. На самом деле, мы говорим "копировать" здесь, они не копируют все.
идентификатор файла здесь относится к обработчику файла. Файловый дескриптор, упомянутый выше, является структурой информации о файле 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