Kann ich einen Eingabedateideskriptor duplizieren und zum Schreiben von Daten verwenden?

Kann ich einen Eingabedateideskriptor duplizieren und zum Schreiben von Daten verwenden?

Der folgende Befehl erstellt eine Kopie des Eingabedateideskriptors und verwendet den duplizierten Dateideskriptor zum Schreiben von Daten aus dem echoBefehl auf das Terminal.

sh-4.2$ exec 6<&0
sh-4.2$ echo "hallo" >&6
Hallo

Bedeutet das, dass wir mit dem Eingabedateideskriptor in das Terminal schreiben können?

Antwort1

Bedeutet das, dass wir mit dem Eingabedateideskriptor in das Terminal schreiben können?

Sicher. Sie können in ein Terminal schreiben (und zwar in jede Datei, Pipe, jedes Gerät oder jeden Socket, der das Schreiben unterstützt und autorisiert), indem Sie den dafür verfügbaren offenen Dateideskriptor verwenden. Eine einfachere Version Ihres Codes wäre diese:

echo hello >&0

was, wie zu erwarten, "hello\n" an den Dateideskriptor sendet, auf den 0 zeigt. Wenn das Ihr Terminal ist, dann ist das so.

Antwort2

Dies ist eine Kopie meiner Antwort auf eineähnliche Frageauf Stackoverflow letztes Jahr.

Sie können aufgrund historischer Gepflogenheiten auf die Standardeingabe Ihres Endgeräts schreiben. Folgendes passiert:

Wenn sich ein Benutzer in einem Terminal auf einem Unix-ähnlichen System anmeldet oder ein Terminalfenster unter X11 öffnet, werden die Dateideskriptoren 0, 1 und 2 mit einem Terminalgerät verbunden und jeder von ihnen wird geöffnet fürsowohl Lesen als auch Schreiben. Das ist der Fallobwohl man normalerweise nur von fd 0 liest und auf fd 1 und 2 schreibt.

Hier ist der Code von7. Ausgabe init.c:

open(tty, 2);
dup(0);
dup(0);
...
execl(getty, minus, tty, (char *)0);

Und so sshfunktioniert es:

ioctl(*ttyfd, TCSETCTTY, NULL);
fd = open("/dev/tty", O_RDWR);
if (fd < 0)
    error("%.100s: %.100s", tty, strerror(errno));
close(*ttyfd);
*ttyfd = fd;
...
/* Redirect stdin/stdout/stderr from the pseudo tty. */
if (dup2(ttyfd, 0) < 0) 
    error("dup2 stdin: %s", strerror(errno));
if (dup2(ttyfd, 1) < 0) 
    error("dup2 stdout: %s", strerror(errno));
if (dup2(ttyfd, 2) < 0) 
    error("dup2 stderr: %s", strerror(errno));

(Die dup2Funktion dupliziert arg1 in arg2 und schließt arg2 bei Bedarf zuerst.)

Und so xtermfunktioniert es:

if ((ttyfd = open(ttydev, O_RDWR)) >= 0) {
    /* make /dev/tty work */
    ioctl(ttyfd, TCSETCTTY, 0);
...
/* this is the time to go and set up stdin, out, and err
 */
{
/* dup the tty */
for (i = 0; i <= 2; i++)
    if (i != ttyfd) {
    IGNORE_RC(close(i));
    IGNORE_RC(dup(ttyfd));
    }
/* and close the tty */
if (ttyfd > 2)
    close_fd(ttyfd);

verwandte Informationen