Na úrovni deskriptoru souboru stdin je definován jako deskriptor souboru 0 , stdout je definován jako deskriptor souboru 1; a stderr je definován jako deskriptor souboru 2 . Viz toto.
I když váš program - nebo shell - změní (např. přesměrování pomocí dup2(2)), co je deskriptor souboru 0, vždy zůstane stdin (protože podle definice STDIN_FILENO
je 0).
Systémová volání jako open(2) nebo pipe(2) nebo socket(2) mohou poskytnout např. STDIN_FILENO
(tj. 0), pokud je tento deskriptor souboru volný (např. protože byl dříve blízko(2)-d). Ale když k tomu dojde, je to stále stdin podle definice.
Samozřejmě, v stdio(3), FILE
stream stdin je trochu složitější. Váš program může fclose(3), freopen(3), fdopen(3) ...
Ačkoli několik odpovědí již existovalo, nepovažoval jsem je za dostatečně informativní, aby vysvětlily celý příběh.
Protože jsem pokračoval a zkoumal více, přidávám své poznatky.
Kdykoli se proces spustí, je do /proc/<pid>
přidán záznam o běžícím procesu adresář. Toto je místo, kde jsou uchovávána všechna data související s procesem. Při spuštění procesu jádro také přidělí procesu 3 deskriptory souborů pro komunikaci se 3 datovými toky označovanými jako stdin
, stdout
a stderr
.
linuxové jádro používá algoritmus k vytvoření FD s nejnižší možnou celočíselnou hodnotou, takže tyto datové toky jsou mapovány na čísla 0
, 1
a 2
.
Protože se nejedná o nic jiného než o odkazy na stream, můžeme stream uzavřít. Jeden může snadno zavolat close(<fd>)
, v našem případě close(1)
, zavřete deskriptor souboru.
při provádění ls -l /proc/<pid>/fd/
, vidíme zde pouze 2 FD 0
a 2
.
Pokud nyní uděláme open()
volání kernel vytvoří nový FD pro mapování této nové reference souboru a protože jádro používá algoritmus nejnižšího celého čísla, vybere si celočíselnou hodnotu 1
.
Takže nyní nový vytvořený FD ukazuje na soubor, který jsme otevřeli (pomocí open()
systémové volání)
Žádný přenos dat, ke kterému nyní dochází, neprobíhá přes výchozí datový proud, který byl dříve propojen, ale přes nový soubor, který jsme otevřeli.
Takže ano, můžeme mapovat FD 0
, 1
nebo 2
do libovolného souboru a není nutné stdin
, stdout
nebo stderr