GNU/Linux >> Znalost Linux >  >> Linux

Je>&- efektivnější než>/dev/null?

Včera jsem četl tento komentář SO, který říká, že v shellu (alespoň bash ) >&- „má stejný výsledek jako“ >/dev/null .

Tento komentář ve skutečnosti odkazuje na průvodce ABS jako zdroj svých informací. Ale ten zdroj říká, že >&- syntaxe „uzavírá deskriptory souborů“.

Není mi jasné, zda jsou dvě akce uzavření deskriptoru souboru a jeho přesměrování na nulové zařízení zcela ekvivalentní. Moje otázka tedy zní:jsou?

Na první pohled se zdá, že zavřít deskriptor je jako zavřít dveře, ale přesměrování na nulové zařízení je otevření dveří do limba! Ty dva mi nepřipadají úplně stejné, protože když uvidím zavřené dveře, nebudu se snažit z nich něco vyhodit, ale když uvidím dveře otevřené, budu předpokládat, že ano.

Jinými slovy, vždy mě zajímalo, zda >/dev/null znamená, že cat mybigfile >/dev/null by ve skutečnosti zpracoval každý bajt souboru a zapsal jej do /dev/null která na to zapomíná. Na druhou stranu, pokud shell narazí na uzavřený deskriptor souboru, mám tendenci si myslet (ale nejsem si jistý), že prostě nic nezapíše, i když otázkou zůstává, zda cat bude stále číst každý bajt.

Tento komentář říká >&- a >/dev/nullměl by “ být stejný, ale není to pro mě tak přesvědčivá odpověď. Chtěl bych mít autoritativnější odpověď s odkazem na standardní nebo zdrojové jádro nebo ne…

Přijatá odpověď:

Ne, to určitě neděláte chcete zavřít deskriptory souborů 0, 1 a 2.

Pokud tak učiníte, při prvním otevření souboru se soubor změní na stdin/stdout/stderr…

Pokud například:

echo text | tee file >&-

Když tee (alespoň některé implementace, jako busybox’) otevře soubor pro zápis, bude otevřen na deskriptoru souboru 1 (stdout). Takže tee napíše text dvakrát do file :

$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "textn", 8193)                 = 5
write(1, "textn", 5)                   = 5
write(1, "textn", 5)                   = 5
read(0, "", 8193)                       = 0
exit_group(0)                           = ?

Bylo známo, že to způsobuje bezpečnostní chyby. Například:

chsh 2>&-

A chsh (aplikace setuid) může skončit zápisem chybových zpráv do /etc/passwd .

Některé nástroje a dokonce i některé knihovny se tomu snaží bránit. Například GNU tee přesune deskriptor souboru na jeden nad 2, pokud jsou soubory, které otevírá pro zápis, přiřazeny 0, 1, 2, zatímco busybox tee nebude.

Související:Linux – Jaký je výchozí soubor pro `hostname`?

Většina nástrojů, pokud nemohou zapisovat do stdout (protože například není otevřená), ohlásí chybovou zprávu na stderr (v jazyce uživatele, což znamená další zpracování pro otevření a analýzu lokalizačních souborů…), takže bude být výrazně méně efektivní a může způsobit selhání programu.

V každém případě to nebude efektivnější. Program bude stále provádět write() systémové volání. Efektivnější to může být pouze tehdy, když se program vzdá zápisu do stdout/stderr po prvním selhání write() systémové volání, ale programy to obecně nedělají. Obvykle buď skončí s chybou, nebo to zkoušejí dál.


Linux
  1. Jak Linux zpracovává více po sobě jdoucích oddělovačů cest (/home////username///soubor)?

  2. Jak přenosné jsou /dev/stdin, /dev/stdout a /dev/stderr?

  3. Kdy použít /dev/random vs /dev/urandom?

  1. Jak úplně umlčet Cronjob do /dev/null/?

  2. Co jsou soubory /dev/zero a /dev/null v Linuxu

  3. Jak kódovat base64 /dev/random nebo /dev/urandom?

  1. Jak spustit soubor sh z jiného souboru sh

  2. obrazovka Nelze otevřít váš terminál '/dev/pts/0' - zkontrolujte prosím

  3. DD z /dev/zero do /dev/null...co se vlastně stane