Beispiele aus der Praxis verwenden dup oder dup2
-
19-09-2019 - |
Frage
ich weiß, was dup
/ dup2
tut, aber ich habe keine Ahnung, wenn es benutzt wird.
Jede praktische Beispiele?
Danke.
Lösung
Ein Beispiel wäre die Verwendung E / A-Umleitung. Für diese Gabel Sie einen Kind-Prozess und in der Nähe der stdin oder stdout Filedeskriptoren (0 und 1) und dann haben Sie eine dup () auf einem anderen FileDescriptor Ihrer Wahl, die jetzt auf den niedrigsten verfügbaren Dateideskriptor zugeordnet werden, die dabei ist, Fall 0 oder 1 ist.
das Verwenden Sie können nun jedes Kind Prozess exec, die möglicherweise von Ihrer Anwendung nicht bewusst ist und immer dann, wenn das Kind schreibt auf dem stdout (oder liest von stdin, was auch immer Sie konfiguriert) die Daten auf der mitgelieferten FileDescriptor geschrieben wird, statt.
Shells verwenden diese Befehle mit Rohren zu implementieren, beispielsweise /bin/ls | more
durch die stdout eines Prozesses zum stdin des anderen zu verbinden.
Andere Tipps
Das beste Szenario zu verstehen, dup und dup2 ist die Umleitung.
Das erste, was wir wissen müssen, ist, dass das System 3 Standarddatei-IDs (oder Variablen angibt, Ausgangs- oder Eingangsquellen), die sich mit dem Ein- und Ausgang. Sie sind stdin
, stdout
, stderr
, in ganzen Zahlen sind sie 0
, 1
, 2
. Die meisten Funktionen wie fprintf
oder cout
sind direkt ausgegeben zu stdout
.
Wenn wir die Ausgabe umleiten möchten, ist eine Möglichkeit geben, zum Beispiel fprintf
Funktion mehr Argumente angibt in
und out
.
Allerdings gibt es eine elegantere Möglichkeit: wir die Standard-Datei IDs überschreiben können, um sie an der Datei vornehmen zeigen wir die Ausgabe erhalten möchten. dup
und dup2
genau arbeiten in dieser Situation.
Beginnen wir mit einem einfachen Beispiel beginnen jetzt: Angenommen, wir die Ausgabe von fprintf
zu einer txt-Datei mit dem Namen „chinaisbetter.txt“ umleiten möchten. Zunächst einmal müssen wir diese Datei öffnen
int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);
Dann wollen wir stdout
zu Punkt "chinaisbetter.txt" von dup-Funktion:
dup2(fw,1);
Jetzt stdout (1) auf den Beschreiber von „chinaisbetter.txt“, obwohl es immer noch 1, aber der Ausgang wird jetzt umgeleitet.
Dann können Sie printf
als normal verwenden, aber die Ergebnisse in der txt-Datei anstatt zu zeigen, direkt auf dem Bildschirm sein werden:
printf("Are you kidding me? \n");
PS :
-
Das gibt nur eine intuitive Erklärung, müssen Sie möglicherweise die Manpage oder detaillierte Informationen überprüfen. Eigentlich, sagen wir, "kopieren" hier sind sie nicht alles zu kopieren.
-
Die Datei-ID bezieht sich hier auf die Handler der Datei. Der Dateideskriptor oben erwähnt ist eine Struktur der Information Aufzeichnungen Datei.
Wenn Sie neugierig nach POSIX-Funktionen sind, vor allem diejenigen, die sich zu vervielfältigen scheinen, ist es im Allgemeinen gut auf überprüfen Sie den Standard selbst . Am unteren Rand finden Sie in der Regel Beispiele zu sehen, sowie Gründe für die Umsetzung (und Existenz) von beiden.
In diesem Fall:
In den folgenden Abschnitten sind informativ.
Beispiele
Umleiten der Standardausgabe in eine Datei
Im folgenden Beispiel wird die Standardausgabe für die laufenden Prozesse, Wiederabtretungsstandardausgabe in die Datei von pfd
verwiesen zu gehen, und schließt die ursprüngliche Dateideskriptor aufzuräumen.
#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...
Umleiten von Fehlermeldungen
Die folgende Beispiel Umleitungen Nachrichten von stderr
zu stdout
.
#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...
Application Usage
Keine.
Begründung
Die dup()
und dup2()
Funktionen sind redundant. Ihre Dienste werden auch von der fcntl()
Funktion zur Verfügung gestellt. Sie haben in diesem Volumen von IEEE Std 1003,1-2001 in erster Linie aus historischen Gründen aufgenommen worden, da viele bestehende Anwendungen nutzen sie.
Während das kurze Codesegment gezeigt im Verhalten dup2()
sehr ähnlich ist, eine konforme Implementierung auf der Grundlage anderen in diesem Volumen von IEEE Std definierten Funktionen 1003,1-2001 ist wesentlich komplexer. Least offensichtlichste ist der mögliche Effekt einer Signalfang-Funktion, die zwischen den Schritten und zuteilen oder DEALLOCATE Filedeskriptoren aufgerufen werden könnte. Dies könnte durch die Blockierung Signale vermieden werden.
Die dup2()
Funktion ist nicht markiert obsolescent, weil es eine typsichere Version von Funktionalität in einem Typ-unsichere Version von fcntl()
bereitgestellt präsentiert. Es wird in dem POSIX-Ada verwendet zu binden.
Die dup2()
Funktion ist nicht für den Einsatz in kritischen Bereichen als Synchronisationsmechanismus.
In der Beschreibung von [EBADF], der Fall von fildes des Bereichs ist, wird durch den gegebenen Fall von fildes bedeckt nicht gültig zu sein. Die Beschreibungen für fildes
und fildes2
sind anders, weil die einzige Art von Invalidität für fildes2
relevant ist, ob es außerhalb des Bereichs liegt; Das heißt, es spielt keine Rolle, ob fildes2
bezieht sich auf eine geöffnete Datei, wenn der dup2()
Anruf getätigt wird.
Future Directions
Keine.
Siehe auch
close()
, fcntl()
, open()
, die Basis Definitionen Volumen von IEEE Std 1.003,1-2.001, <unistd.h>
Änderungsverlauf
Zuerst in Ausgabe 1 veröffentlicht von Ausgabe Abgeleitet 1 des SVID.
Ein praktisches Beispiel ist Umleiten Ausgabenachrichten an einen anderen Strom wie eine Log-Datei. Hier ist ein Beispielcode für E / A-Umleitung.
Bitte beachten Sie Original-Beitrag hier
#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()");
}
E / A-Umleitung in der Schale am ehesten umgesetzt würde dup2 / fcnlt Systemaufrufe verwenden.
Wir können leicht die $program 2>&1 > logfile.log
Art der Umleitung emulieren die dup2 Funktion.
Das folgende Programm Umleitungen sowohl stdout und stderr .i.e emuliert Verhalten von $program 2>&1 > output
die dup2 verwenden.
#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