Was bedeutet das folgende Skript?
exec 4<&0 0</etc/XX/cfg
read line1
exec 0<&4
Es leitet fd0 zu fd4 und „/etc/XX/cfg“ zu fd0 um.
Warum funktioniert es also read
immer noch, sollte das nicht leer sein?
Antwort1
Es leitet stdin (FD0) zu FD4 um, leitet von dort /etc/XX/cfg
zu FD0 um, liest eine Zeile von FD0 und verschiebt dann FD4 zurück zu FD0. Kurz gesagt, es speichert, ersetzt und stellt stdin wieder her, während es zwischendurch eine Zeile aus einer Datei liest.
read line1 < /etc/XX/cfg
wäre viel einfacher, aber es ist unmöglich, nur anhand des angezeigten Codes zu sagen, ob es sich um einen gültigen Ersatz handelt.
Antwort2
So formulieren Sie dies in Systemaufrufen um (mit C):
exec 4<&0 0</etc/XX/cfg
/* Duplicate fd0 as fd4. */
dup2 (0, 4);
/* Open file on fd0.
"open" always uses lowest available descriptor, so we don't need to check it. */
close (0);
open ("/etc/XX/cfg", O_RDONLY);
exec 0<&4
/* Close fd0 and duplicate fd4 as fd0. */
dup2 (4, 0);
Antwort3
So wie ich das verstehe – basierend auf dem Abschnitt zur UMLEITUNG auf der Bash-Manpage – wird stdin
(fd0) in fd4 umgeleitet, dann wird die Eingabe von /etc/XX/cfg
into übernommen stdin
, was auf fd4 endet.
read line1
sollte dann von fd4 nehmen, was dann wieder zu fd0 zurückgesetzt wird.
Eine Demo könnte das, was ich meine, besser verdeutlichen und die Frage beantworten, warum Sie das tun. Fügen Sie dazu eine weitere Zeile hinzu und packen Sie sie in einen Wrapper:
$ vim ./test.sh
#!/bin/bash
exec 4<&0 0</etc/XX/cfg
read line1 # reads from fd4
exec 0<&4
read line2 # reads from fd0
echo $line1
echo $line2
Sie können über test.sh weiterleiten oder umleiten, stdin
aber auch die Konfiguration per Umleitung einlesen. Im obigen Code habe ich also Werte aus der „Konfiguration“ übernommen (Annahme meinerseits aufgrund des Dateinamens – falsch :)), ich kann die Verarbeitung aber auch über stdin durchführen.
z.B:
$ ./test.sh < somefile
$ cat somefile | ./test.sh
Hoffentlich erklärt das es.