Bazı çaylakların cevaplarımdan biri için UUOC'yi bana doğru tutmaya çalıştığı güne dek bu ödülün farkında değildim. Öyleydi cat file.txt | grep foo | cut ... | cut ...
. Ona aklımdan bir parça verdim ve ancak bunu yaptıktan sonra bana ödülün kökenlerine ve bunu yapma pratiğine değinen bağlantıyı ziyaret etti. Daha fazla arama beni bu soruya yönlendirdi. Ne yazık ki, bilinçli bir değerlendirmeye rağmen, cevapların hiçbiri mantığımı içermiyordu.
Onu eğitirken savunmacı olmak istemedim. Ne de olsa, daha genç yaşlarımda emir olarak yazdım grep foo file.txt | cut ... | cut ...
çünkü sık sık beklediğiniz zaman grep
dosya argümanının yerleşimini öğreniyorsunuz ve birincinin desen, daha sonra da dosya isimlerinin ne olduğunu bilmeye hazır.
Öncelikle soruyu cat
kısmen “iyi tat” (Linus Torvalds'ın sözleriyle) bir nedeni nedeniyle ama esas olarak zorlayıcı bir işlev sebebi nedeniyle yanıtladığımda bilinçli bir seçimdi .
İkinci sebep daha önemlidir, bu yüzden önce onu açıklayacağım. Bir çözüm olarak bir boru hattı önerdiğimde, yeniden kullanılabilir olmasını bekliyorum. Bir boru hattının sonuna eklenmesi veya başka bir boru hattına eklenmesi muhtemeldir. Bu durumda, yeniden kullanılabilirliği arttırmak için bir dosya argümanına sahip olmak ve dosya argümanı mevcutsa , büyük olasılıkla sessizce bir hata mesajı olmadan bunu yapmak . I. e. grep foo xyz | grep bar xyz | wc
kaç satır size verecektir xyz
içerirler bar
hem içerirler satır sayısını bekliyoruz ederken foo
ve bar
. Argümanları kullanmadan önce bir boru hattındaki bir komuta değiştirmek zorunda kalmak hatalara açıktır. Sessiz başarısızlık olasılığını eklediğinizde, bu özellikle sinsi bir uygulama haline gelir.
İlk sebep, çok fazla "iyi tadı" olan sadece önemsiz değildir, çünkü yukarıda belirtilen, başarısızlık gibi şeyler için sezgisel, bilinçli bir mantıktır, çünkü şu an için eğitime ihtiyacı olan bir kişinin söylediği anda düşünemezsiniz " bu kedi işe yaramaz ".
Ancak, bahsettiğim eski "iyi tat" sebebini de bilinçlendirmeye çalışacağım. Bu nedenle Unix'in dik tasarım ruhuyla ilgisi var. grep
değil cut
ve ls
değil grep
. Bu nedenle en azından grep foo file1 file2 file3
tasarım ruhuna aykırıdır. Bunu yapmanın ortogonal yolu cat file1 file2 file3 | grep foo
. Şimdi, grep foo file1
sadece özel bir durumdur grep foo file1 file2 file3
ve aynı şekilde muamele etmezseniz, en azından işe yaramaz kedi ödülünden kaçınmaya çalışırken beyin saati döngülerini kullanıyorsunuzdur.
Bu bizi grep foo file1 file2 file3
birleştiren ve cat
birleştiren argümana götürür , böylece uygun olur, cat file1 file2 file3
ancak cat
birleştirici olmadığı cat file1 | grep foo
için, hem de cat
hem de yüce Unix'in ruhunu ihlal ediyoruz . Öyleyse, durum böyle olsaydı, Unix bir dosyanın çıktısını okumak ve onu stdout'a tükürmek için farklı bir komuta ihtiyaç duyardı (onu sayfalandırmak ya da sadece stdout'a saf bir tükürük vermek için değil). Yani söylediğiniz cat file1 file2
veya söyleyeceğiniz bir duruma sahip olacaksınız dog file1
ve cat file1
ödülü almaktan kaçınmak için vicdanlı bir şekilde hatırlayacağınız bir yandan da kaçınmaktan kaçının dog file1 file2
çünkü umarım dog
birden fazla dosya belirtilirse tasarım bir hata verecektir.
Umarım bu noktada, Unix tasarımcılarına bir dosyayı stdout'a tükürmek için ayrı bir komut eklememekle ve aynı zamanda cat
başka bir isim vermek yerine birleştirmek için adlandırma konusunda sempati duyarsınız . <edit>
talihsiz <
operatör gibi bir köpek var . Kolay birleştirilebilirliği önleyen boru hattının sonuna yerleştirilmesi talihsiz bir durumdur. Başına yerleştirmenin sözdizimsel veya estetik açıdan temiz bir yolu yoktur. Aynı zamanda yeterince genel olmamak da talihsiz bir durumdur, bu nedenle köpekle başlayabilirsiniz, ancak bir öncekinden sonra da işlenmesini istiyorsanız başka bir dosya adı ekleyin. ( >
Öte yandan, yarısı kadar kötü değildir. Sonunda neredeyse mükemmel bir yerleşime sahiptir. Tipik olarak bir boru hattının tekrar kullanılabilir bir parçası değildir ve buna göre sembolik olarak ayırt edilir.)</edit>
Bir sonraki soru, başka bir işlem yapmadan sadece bir dosyayı ya da birkaç dosyanın stdout'u birleştirmesini sağlayan komutlara sahip olmanın neden bu kadar önemli? Bunun bir nedeni, standart girdi üzerinde çalışan her bir Unix komutunun en az bir komut satırı dosyası argümanının nasıl ayrıştırılacağını ve varsa girdi olarak nasıl kullanılacağını bilmek istememesidir. İkinci sebep, kullanıcıların hatırlamak zorunda kalmamasıdır: (a) dosya adı argümanlarının gittiği yer; ve (b) yukarıda belirtildiği gibi sessiz boru hattı hatasını önlemek.
Bu bize neden grep
ekstra mantığa sahip olduğunu gösteriyor. Bunun gerekçesi, sık kullanılan ve tek başına bir temelde (bir boru hattı olarak) kullanılan komutlar için kullanıcının akıcılığını sağlamaktır . Kullanılabilirlikte önemli bir kazanç elde etmek için hafif bir ortogonalite uzlaşmasıdır. Tüm komutlar bu şekilde tasarlanmamalı ve sık kullanılmayan komutlar, dosya argümanlarının ekstra mantığından tamamen kaçınmalıdır (fazladan mantığın gereksiz kırılganlığa yol açtığını unutmayın (bir hata olasılığı)). Bunun istisnası, olduğu gibi dosya argümanlarına izin vermektir grep
. (bu arada ls
sadece kabul etmekle kalmayıp aynı zamanda dosya argümanları gerektirmek için tamamen farklı bir nedene dikkat edin )
Son olarak, daha iyi yapılabilecekler, eğer standart giriş mevcutsa, istisnai olarak verilen komutların grep
(ancak zorunlu olmamak üzere ls
) bir hata üretmesidir. Bu mantıklıdır çünkü komutlar, kullanıcı rahatlığı için her şeye rağmen Unix'in ortogonal ruhunu ihlal eden bir mantık içerir. Daha fazla kullanıcı rahatlığı için, yani sessiz bir arızadan kaynaklanan ıstırabın önlenmesi için, bu komutların, sessiz bir arıza olasılığı varsa kullanıcıyı uyaran kendi ihlallerini ihlal etmekte tereddüt etmemesi gerekir.