2012-04-14 5 views
8

In bash können Sie tun:gibt es Verwendungen für '> & 0' (Redirect to Stdin)?

  • echo test >&1 (Umleitung auf stdout, obwohl es dort schon los)
  • echo test >&2 (Umleitung auf stderr)
  • echo test >&0 (Umleitung auf stdin)

Wenn ich die letzte mache, druckt mein Terminal immer noch test, wie es mit den anderen beiden wäre, aber es ist schwer zu wissen, warum. Also zuerst, warum funktioniert das überhaupt? Zweitens, gibt es einen guten Nutzen für die Umleitung auf Stdin?

Antwort

6

Um genauer zu sein, was >&0 tut, ist Dateideskriptor 0 als Dateideskriptor 1 zu duplizieren. Wenn die Programmeingabe nur zum Lesen geöffnet ist, dann wird es, wenn Ihr Programm versucht, in stdout (Dateideskriptor 1) zu schreiben ein Fehler, weil Dateideskriptor 1 auch nur zum Lesen geöffnet ist.

Sie können dies zeigen, indem sie einen kleinen Shell-Skript zu schreiben, das seine eigenen Filedeskriptoren inspiziert:

10156115.sh:

#!/bin/bash 
bash -c 'ls -l /proc/$$/fd' >&0 

Und dann rufen Sie es mit identifizierbarem stdin, stdout und stderr:

$ touch stdin 
$ ./10156115.sh <stdin> stdout 2> stderr 

das Ergebnis ist, dass Sie die folgenden in stderr erhalten:

ls: write error: Bad file descriptor 

jedoch standardmäßig alle drei sind ein Terminal (Ausgabe vereinfacht)

$ ls -l /proc/$$/fd 
lrwx------ 0 -> /dev/pts/14 
lrwx------ 1 -> /dev/pts/14 
lrwx------ 2 -> /dev/pts/14 
lrwx------ 255 -> /dev/pts/14 

Typischerweise alle drei sind tatsächlich offene Lese + schreiben, so dass die >&0 Umleitung hat überhaupt keine Wirkung, wenn allein verwendet, aus einer normalen Shell.


Gibt es irgendwelche Verwendungen dafür?

Es gibt keine gemeinsame Nutzung von dieser, aber Sie könnten es als schmutzig Hack verwenden, um einen Weg, um an das Terminal zu drucken, wenn wer auch immer Ihr Skript ruft umleitet stdout und stderr, und aus irgendeinem Grund sind Sie nicht kann das ändern:

if [ ! -t /dev/fd/1 -a ! -t /dev/fd/2 -a -t /dev/fd/0 ]; then 
    echo "My message that I really, really want to go to a terminal" >&0 
fi 

Aber ich würde nicht empfehlen, dies tatsächlich zu tun.

5

Aus historischen Gründen sind die Standarddateideskriptoren auf einem Terminal lesend/schreibend statt schreibgeschützt (speziell wird es einmal geöffnet und dup() ed zu den anderen). Dies ist gelegentlich nützlich für Programme, die piped Eingabe, aber auch Leseeingabe vom Benutzer (von stdout oder häufiger stderr), obwohl /dev/tty in diesem Fall zuverlässiger ist. Einige Systeme wenden dies auf mehr als nur ttys an: Die * BSDs öffnen bockseitig offene Socketpairs ("Pipes"), und einige System-Utilities (ich erinnere mich beispielsweise an ufsdump) hängen davon ab.

Umleiten -stdin (das heißt, sich zum Schreiben nur mit offenen) ist im Allgemeinen nicht sinnvoll, da die meisten Programme erwarten, dass es bis zum Lesen geöffnet sein (oder manchmal lesen/schreiben, wie oben).

Verwandte Themen