Mám velmi těžké pochopit, jak se používají deskriptory souborů ve skriptech shellu.
Znám základy jako je
exec 5 > /tmp/foo
Takže fd 5 je připojen k foo pro zápis.
exec 6 < /tmp/bar
… ke čtení.
exec 5>&-
… zavřít fd.
Co to teď dělá?
#!/bin/bash
exec 5 > /tmp/foo
exec 6 < /tmp/bar
cat <&6 | while read a
do
echo $a >&5
done
Pokud rozumím &5
zavře fd, tak jak je výstup stále úspěšně přesměrován po každém volání?
Toto je kopie těstovin z:Zde
Tvrdí, že to používá přes jednoduchý echo $a > file
by to bylo mnohem rychlejší, ale nerozumím tomu. Ocenil bych jakýkoli odkaz na slušný tutoriál. Zdá se, že schopnosti googlu mě selhávají.
Přijatá odpověď:
Nejprve si všimněte, že syntaxe pro uzavření je 5>&-
nebo 6<&-
v závislosti na tom, zda je deskriptor souboru čten pro zápis nebo pro čtení. Zdá se, že v tomto blogovém příspěvku je překlep nebo chyba formátování.
Zde je komentovaný skript.
exec 5>/tmp/foo # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar # open /tmp/bar for reading, on fd 6
cat <&6 | # call cat, with its standard input connected to
# what is currently fd 6, i.e., /tmp/bar
while read a; do #
echo $a >&5 # write to fd 5, i.e., /tmp/foo
done #
Není zde žádné zavírání. Protože všechny vstupy a výstupy jdou v tomto jednoduchém příkladu na stejné místo, není nutné použití dalších deskriptorů souborů. Mohl bys napsat
cat </tmp/bar |
while read a; do
echo $a
done >/tmp/foo
Použití explicitních deskriptorů souborů je užitečné, když chcete zapisovat do více souborů postupně. Zvažte například skript, který odesílá data do výstupního souboru dat a zaznamenává data do souboru protokolu a případně také chybové zprávy. To znamená tři výstupní kanály:jeden pro data, jeden pro protokoly a jeden pro chyby. Protože pro výstup existují pouze dva standardní deskriptory, je potřeba třetí. Můžete zavolat exec
k otevření výstupních souborů:
exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&- # close the data output file
echo "output file closed" >&3
Poznámka o účinnosti přichází, když máte přesměrování ve smyčce, jako je tato (předpokládejme, že soubor je pro začátek prázdný):
while …; do echo $a >>/tmp/bar; done
Při každé iteraci program otevře /tmp/bar
, vyhledá konec souboru, připojí některá data a soubor zavře. Je efektivnější otevřít soubor jednou provždy:
while …; do echo $a; done >/tmp/bar
Pokud dojde k více přesměrování v různých časech, volání exec
je užitečné provádět přesměrování namísto zabalení bloku do přesměrování.
exec >/tmp/bar
while …; do echo $a; done
Několik dalších příkladů přesměrování najdete procházením io-redirection
tag na tomto webu.