Named Pipe
Bu bölümde programların standart girdi ve çıktılarını birbirlerine veya çeşitli dosyalara yönlendirme işlemlerinin detaylarını gördük. Özellikle UNIX pipeline'ı oluşturan bu süreçte, genellikle programları birbirleriyle bağlarken |
işaretinin nasıl kullanıldığını gördük.
Bu kullanımdaki temel problemler, programlar arasındaki bağlantının tek seferlik yapılması, tek yönlü olması ve tek yazılım tarafından kullanılabilmesi. Örneğin bir programın çıktısının birden fazla program tarafından girdi olarak kullanılmasını sağlamak, veya birden fazla programın girdi sağlayabileceği ortam sağlamak mümkün olmaz.
Bunun için named pipe denilen dosyalar kullanılır. Hatırlarsanız daha önce "UNIX üzerinde her şey bir dosyadır" demiştik. Burada da özel bir dosya tipinden bahsediyoruz. Sistem üzerinde öyle bir dosya tanımlanır ki, bu dosyaya birden fazla program yazabilir, ve bu dosyayı birden fazla program okuyabilir. Üstelik bu dosya hiç yer kaplamaz. Aslında daha önce kullandığımız pipe işleminin sadece iki program arasında değil, birden fazla program arasında kullanılmasına olanak sağlar. Bunu yapmak için dosya sistemi üzerinde ilgili pipe'ı isimlendirmemiz gerektiğinden, bunlara named pipe denilir. Böyle olunca da, daha önce kullandığımız pipe işaretlerine anonymous pipe (anonim pipe) veya regular pipe (normal pipe) denilir.
Named pipe'lar, üzerine yazılan verinin aynı sırayı koruyarak okunmasını sağlarlar. Kısacası ilk yazdığımız veri, ilk okunacak veridir. Bu tip sistemlere First In First Out'un kısaltması olan FIFO denilir. Yani işleme alınacak verilerde öncelik, en eski oluşturulan veriye tanınır. Örneğin bunun bir alternatifi, Last In First Out'un kısaltması olan LIFO'lardır. Ancak named pipe'lar, FIFO şeklinde çalıştığı için, aşağıdaki komut ile bir named pipe oluşturulur.
Bu işlem sonucunda aslında ~/devel/namedpipe
dizini içinde mario
isimli özel bir dosya oluşmuştur. Bu dizinin içeriğine bakacak olursak:
Burada mario
'nun dosya tipinin p olduğu görülüyor. Bu, dosyanın pipe olduğunu ifade etmektedir. Gördüğünüz üzere dosyanın boyutu da 0 Byte'dır. Yani disk üzerinde yer kaplamaz.
Eğer aşağıdaki gibi ufak bir script yazarsak, çalıştırıldığında her saniye mevcut tarih/saati standart çıktıya yazdırmasını sağlayabiliriz. Bu script'i telltime.sh
olarak kaydettiğimizi düşünelim.
Eğer bu scripti çalıştırıp standart çıktısını mario
'ya yönlendirirsek, sonra başka bir terminal üzerinden mario
'yu okursak, her saniye tarih/saati görmeyi bekleriz.
Tahmin edeceğiniz üzere, mario'yu birden fazla programın okumasını da sağlayabilirdik.
Şimdi bir başka program yazalım, ve bu program da iki saniyede bir VeriTeknik sözcüğünü standart çıktıya yazsın.
Biraz önce çalıştırdığımız ./telltime.sh > mario
komutu hala çalışmaya devam ederken, bir de ./tellname.sh > mario
komutunu farklı terminalde çalıştırabiliriz. Böylece telltime
scripti her saniye mario
'ya saati yazacak, tellname
scripti ise her iki saniyede bir mario
'ya VeriTeknik
yazacaktır. Sonucu yine farklı bir terminalde mario
'yu okuyarak gözleyebiliriz.
Özellikle başlarda ve sonlarda 2'den fazla saat satırı görmeniz normal, çünkü tellname
scriptini arada çalıştırıp durdurduk. Yukarıdaki örnekten tellname
scriptini saat 16:09:24'te çalıştırdığımızı ve 16:09:33 veya 16:09:34'te durdurduğumuzu anlayabiliriz. Yani mario
pipe'ına aynı anda yeni programlar veri yazıp durdurabilir, ve okuyan taraf sadece sonuçları görerek etkilenir. Dosyayı yeniden açıp kapatmasına bile ihtiyaç duymaz.
Named pipe'lar hakkında GNU/Linux manual sayfalarında önemli bir bilgi yer alır.
The FIFO must be opened on both ends (reading and writing) before data can be passed. Normally, opening the FIFO blocks until the other end is opened also.
Yani bir named pipe oluşturduğumuzda, eğer aynı anda okuyan ve yazan birileri varsa veri akışı sağlanır. Yoksa bir taraftan sürekli yazsanız bile, bunu okuyan birileri olmadığı sürece o veri kaybolur. Tıpkı /dev/null
dosyasına yazmışsınız gibi veri hiçbir yere kaydedilmez.
Named pipe'lar ile yapılan işlemlerin dosya sisteminde inode oluşturmak dışında herhangi bir yük oluşturmadığını hatırlatmakta fayda var. Birden fazla programın birbiriyle iletişim kurmasını sağlayan bu mekanizma tamamen çekirdek (kernel) tarafından idare edilir.
Oluşturduğunuz bir named pipe'ı rm
komutuyla kolayca silebilirsiniz.
Last updated