Dosya tanımlayıcıları ve kabuk komut dosyası oluşturma


32

Bir kişinin kabuk betiklerinde dosya tanımlayıcılarını nasıl kullandığını anlamakta zorlanıyorum.

Gibi temel bilgileri biliyorum

exec 5 > /tmp/foo

Öyleyse fd 5 yazı için yazıya eklenir.

exec 6 < /tmp/bar

… okumak için.

exec 5>&-

… Fd'yi kapatın.

Şimdi bu ne yapıyor?

#!/bin/bash

exec 5 > /tmp/foo 
exec 6 < /tmp/bar 

cat <&6 | while read a
do
     echo $a >&5
done

Anladığım kadarıyla &5fd'yi kapatıyor, peki çıkış her aramadan sonra nasıl başarılı bir şekilde yönlendiriliyor?

Bu bir kopyasını makarna: İşte

Bunu basit bir şekilde kullanmanın echo $a > fileçok daha hızlı olacağını iddia ediyor , ancak anlayamadım. İyi öğretici herhangi bir bağlantı için teşekkür ederiz. Ben google güçler beni başarısız görünüyor.

Yanıtlar:


44

İlk olarak, kapatma sözdiziminin 5>&-veya 6<&-dosya tanımlayıcısının yazma veya okuma için okunup okunmadığına bağlı olduğunu unutmayın . Bu blog yazısında bir yazım hatası veya biçimlendirme sorunu var görünüyor.

İşte yorumlanan komut dosyası.

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                  # 

Burada kapanış yok. Bu basit örnekte tüm giriş ve çıkışlar aynı yere gideceğinden, fazladan dosya tanımlayıcıların kullanılması gerekli değildir. Yazabilirsin

cat </tmp/bar |
while read a; do
  echo $a
done >/tmp/foo

Açık dosya tanımlayıcıları kullanmak, sırayla birden fazla dosyaya yazmak istediğinizde yararlı olur. Örneğin, veriyi bir veri çıktı dosyasına gönderen bir komut dosyasını ve bir günlük dosyasına veri kaydı ve muhtemelen hata mesajlarını düşünün. Bu, üç çıkış kanalı anlamına gelir: biri veri, biri günlük, diğeri hatalar içindir. Çıktı için sadece iki standart tanımlayıcı olduğundan, üçte birine ihtiyaç vardır. execÇıktı dosyalarını açmak için arayabilirsiniz :

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

Verimlilik ile ilgili sözler, bir döngüde yeniden yönlendirme olduğunda gelir, bunun gibi (dosyanın başının boş olduğunu varsayalım):

while …; do echo $a >>/tmp/bar; done

Her yinelemede, program açılır /tmp/bar, dosyanın sonuna bakar, bir miktar veri ekler ve dosyayı kapatır. Dosyayı bir kez ve herkes için açmak daha verimlidir:

while …; do echo $a; done >/tmp/bar

Farklı zamanlarda birden fazla yönlendirme execolduğunda, bir yönlendirme içinde bir bloğu sarmak yerine yeniden yönlendirme yapmak için çağrı yapmak yararlı olur.

exec >/tmp/bar
while …; do echo $a; done

Bu sitedeki etikete göz atarakio-redirection başka yönlendirme örnekleri de bulacaksınız .


1
Her iki dosya tanımlayıcısını kapatmak için sözdizimi aslında aynı şeyi yapar.
user1338062
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.