Bir dosya tanımlayıcısını kaydetmek için, dosyayı başka bir fd'de çoğaltırsınız. İlgili dosyaya bir yol kaydetmek yeterli değildir, açılış modunu, açılış bayraklarını, dosyadaki geçerli konumu vb. Kaydetmeniz gerekir. Ve elbette, anonim borular veya soketler için, bunların yolu olmadığı için işe yaramaz. Kaydetmek istediğiniz şey, fd'nin başvurduğu açık dosya açıklamasıdır ve bir fd'yi çoğaltmak aslında yeni bir fd'yi aynı açık dosya tanımına döndürür .
Bourne benzeri bir kabukla bir dosya tanımlayıcısını diğerine çoğaltmak için sözdizimi şöyledir:
exec 3>&1
Yukarıda fd 1, fd 3 üzerine kopyalanmıştır.
Fd 3 daha önce açık olan her neyse kapatılacaktı, ancak 3 ila 9 arasındaki disklerin (genellikle daha fazla, 99'a kadar yash
) bu amaç için ayrıldığını (ve 0, 1 veya 2'nin aksine özel bir anlamı olmadığını) unutmayın. shell bunları kendi iç işleri için kullanmamayı bilir. Fd 3'ün önceden açık olmasının tek nedeni, komut dosyasında 1 yapmış olmanız ya da arayan tarafından sızdırılmış olmasıdır.
Ardından stdout'u başka bir şeye değiştirebilirsiniz:
exec > /dev/null
Ve sonra, stdout'u geri yüklemek için:
exec >&3 3>&-
( 3>&-
artık ihtiyacımız olmayan dosya tanımlayıcısını kapatmak).
Şimdi, bununla ilgili sorun, ksh dışında, bundan sonra çalıştırdığınız her komutun exec 3>&1
fd 3'ü miras alacağıdır. Genellikle çok önemli değil, ama bu soruna neden olabilir.
ksh
bu fds üzerinde yürütme yakın bayrağını ayarlar (2'den büyük fds için), ancak diğer mermilerin ve diğer mermilerin bu bayrağı manuel olarak ayarlamak için herhangi bir yolu yoktur.
Diğer kabuk için çözüm, her komut için fd 3'ü kapatmaktır, örneğin:
exec 3>&-
exec > file.log
ls 3>&-
uname 3>&-
exec >&3 3>&-
Hantal. Burada, en iyi yol hiç kullanmamak exec
, ancak komut gruplarını yönlendirmek olacaktır:
{
ls
uname
} > file.log
Orada, stdout'u kaydetmeye ve daha sonra geri yüklemeye özen gösteren kabuktur (ve exec-close-off bayrak seti yash
ile bir fd'de (9'un üzerinde, 99'un üzerinde) çoğaltarak dahili olarak yapar ).
Not 1
Şimdi, bu fds 3 ila 9'un yönetimi, yoğun veya işlevlerde, özellikle de komut dosyanız bu fds'yi kullanabilen bazı üçüncü taraf kodları kullanıyorsa, hantal ve sorunlu olabilir.
Bazı kabuklar ( zsh
, bash
, ksh93
, bütün özelliği (katma Oliver dalyan önerdiğizsh
bu durumda yardımcı olur yerine 10'un üzerinde ilk serbest fd atamak için alternatif bir sözdizimi var onların geliştiriciler arasında tartışıldı sonra 2005 yılında aynı zamanda etrafında)):
myfunction() {
local fd
exec {fd}>&1
# stdout was duplicated onto a new fd above 10, whose actual value
# is stored in the fd variable
...
# it should even be safe to re-enter the function here
...
exec >&"$fd" {fd}>&-
}