GNU/Linux >> Znalost Linux >  >> Linux

Význam symbolů šipek v duplikování/zavírání deskriptorů souborů pod Bash?

Čtu knihu o příkazovém řádku Linuxu, kde se zdá, že autor nedodržuje konvence v bash manuálu týkající se symbolů šipek používaných při operacích přesměrování. Konkrétně vždy používá šipku vlevo < při duplikování a zavírání deskriptorů souborů bez ohledu na to, zda jsou deskriptory vstupní nebo výstupní.

Zde je příklad:

exec 3<&0 4<&1 #shouldn't be 4>&1 ?
#...
exec 3<&- 4<&- #shouldn't be 4>&- ?

Manuální stránka Bash je v tomto bodě vágní, podle ní mají popisovače duplikování/zavírání a přesouvání souborů následující syntaxe:

#Duplicating and closing (in case word expands to -):
[n]<&word 
[n]>&word

#Moving:
[n]<&digit-
[n]>&digit-

Je popsáno, že mají odlišné chování pouze v případě, že výslovně neuvedeme n . Ale když to uděláme, znamená to, že můžeme tyto formy používat zaměnitelně?

Přijatá odpověď:

Nezáleží na tom, protože oba 4>&1 a 4<&1 proveďte totéž:dup2(1, 4) což je systémové volání pro duplikování fd na jiné. Duplikovaný fd automaticky zdědí I/O směr původního fd. (stejné pro 4>&- vs 4<&- které se oba vyhodnotí jako close(4) a 4>&1- což je dup2(1, 4) následuje close(1) ).

Nicméně 4<&1 syntaxe je matoucí, pokud z nějakého důvodu nebyl fd 1 výslovně otevřen pro čtení (což by bylo ještě více matoucí), takže bych se tomu podle mého názoru měl vyhnout.

Duplicitní fd sdílí stejný popis otevřeného souboru což znamená, že sdílejí stejný offset v souboru (pro ty typy souborů, kde to dává smysl) a stejné související příznaky (režim přesměrování/otevření I/O, O_APPEND atd.).

V systému Linux existuje další způsob, jak duplikovat fd (což ve skutečnosti není duplikace) a vytvořte nový popis otevřeného souboru pro stejný zdroj, ale možná s různými příznaky.

exec 3> /dev/fd/4

Zatímco na Solarisu a pravděpodobně většině ostatních Unices, to je víceméně ekvivalentní dup2(4, 3) , na Linuxu, který otevře stejný zdroj jako ten, na který odkazuje fd 4 od začátku.

To je důležitý rozdíl, protože například pro běžný soubor bude offset fd 3 0 (začátek souboru) a soubor bude zkrácen (proto například na Linuxu musíte napsat tee -a /dev/stderr místo tee /dev/stderr ).

Související:Jak sdělit Firefoxu, aby používal jiné zařízení ALSA?

A režim I/O se může lišit.

Je zajímavé, že pokud fd 4 ukazoval na čtecí konec roury, pak fd 3 nyní ukazuje na zapisovací konec (/dev/fd/3 chová se jako pojmenovaný kanál ):

$ echo a+a | { echo a-a > /dev/fd/0; tr a b; }
b+b
b-b

$ echo a+a | { echo a-a >&0; tr a b; }
bash: echo: write error: Bad file descriptor
b+b

Linux
  1. Další hloupé Bashovy triky:Proměnné, hledání, deskriptory souborů a vzdálené operace

  2. Může být Bash skript připojen k souboru?

  3. Vlákna a deskriptory souborů

  1. Deskriptory souborů a skriptování prostředí?

  2. The Bash ‘?

  3. Provádění operací atomového zápisu v souboru v Bash?

  1. Bash Script:Zkontrolujte, zda je soubor textovým souborem?

  2. Jak analyzovat soubor CSV v Bash?

  3. Bash:Žádný takový soubor nebo adresář?