/ Dev / null yönüne yönlendirmek için tek veya çift açılı parantez kullanmalı mıyım?


18

Buradaki yanıtların çoğu [ 1 ] [ 2 ] [ 3 ] / dev / null öğesine yönlendirmek için tek bir açılı ayraç kullanır, şöyle:

command > /dev/null

Ancak / dev / null öğesine eklemek de işe yarar:

command >> /dev/null

Ekstra karakter hariç, bunu yapmamak için herhangi bir neden var mı? Bunlardan herhangi biri / dev / null öğesinin altında yatan uygulama için "daha güzel" midir?

Düzenleme: open (2) manpage diyor lseek modu ekleme bir dosyaya her yazma önce denir:

O_APPEND
Dosya ekleme modunda açılır. Her yazma işleminden önce (2), dosya ofseti, lseek (2) ile olduğu gibi, dosyanın sonuna konumlandırılır. Dosya ofsetinin değiştirilmesi ve yazma işlemi tek bir atomik adım olarak gerçekleştirilir.

bu da kullanmak için küçük bir performans cezası olabileceğini düşündürüyor >>. Ancak diğer yandan, / dev / null kısaltması bu belgeye göre tanımlanmamış bir işlem gibi görünüyor:

O_TRUNC
Dosya zaten varsa ve normal bir dosyaysa ve erişim modu yazmaya izin veriyorsa (yani, O_RDWR veya O_WRONLY ise) 0 uzunluğuna kısaltılır. Dosya bir FIFO veya terminal aygıt dosyasıysa, O_TRUNC bayrağı yoksayılır. Aksi takdirde, O_TRUNC'nin etkisi belirtilmez.

ve POSIX spesifikasyonu >mevcut bir dosyayı kısaltacağını söylüyor , ancak O_TRUNC cihaz dosyaları için uygulama tanımlı ve / dev / null öğesinin kısaltılmaya nasıl yanıt vermesi gerektiği hakkında bir kelime yok .

Peki, truncating / dev / null belirtilmemiş mi? Ve lseek çağrılarının yazma performansı üzerinde herhangi bir etkisi var mı?

Yanıtlar:


27

Tanım gereği /dev/null, ona yazılan herhangi bir şeyi batırır , bu nedenle ekleme modunda yazıp yazmamanız önemli değildir, hepsi atılır. Verileri saklamadığından, eklenecek hiçbir şey yoktur.

Sonuçta, > /dev/nullbir >işaretle yazmak daha kısadır .

Düzenlenen ek için:

Open (2) manpage, lseek'in ekleme modunda her dosyaya yazılmadan önce çağrıldığını söylüyor.

Yakından okursanız, şunu görürsünüz (benimkini vurgulayın):

dosya ofseti, lseek (2) ile olduğu gibi , dosyanın sonuna konumlandırılır

Yani, lseeksistem çağrısını gerçekten çağırmaz (buna gerek yoktur) ve etki de kesinlikle aynı değildir: lseek(fd, SEEK_END, 0); write(fd, buf, size);onsuz çağrı O_APPENDekleme modunda bir yazma ile aynı değildir, çünkü ayrı çağrılarla başka bir süreç sistem çağrıları arasında dosya ekleyerek eklenmiş verileri çöpe atar. Ekleme modunda bu gerçekleşmez ( gerçek ekleme modunu desteklemeyen NFS dışında ).

Standarttaki metinlseek bu noktada bahsetmez , sadece dosyanın sonuna kadar yazar.

Peki, truncating / dev / null belirtilmemiş mi?

Bahsettiğiniz yazılara bakılırsa, görünüşe göre uygulama tanımlıdır. Herhangi bir aklı başında uygulama, borular ve TTY'ler ile aynı şeyi yapacaktır, yani hiçbir şey yapmaz. Çılgın bir uygulama başka bir şey yapabilir ve belki de kısaltma, başka bir cihaz dosyası durumunda mantıklı bir şey anlamına gelebilir.

Ve lseek çağrılarının yazma performansı üzerinde herhangi bir etkisi var mı?

Dene. Belirli bir sistemde emin olmanın tek yolu budur. Ya da ekleme modunun herhangi bir yerde davranışı nerede değiştirdiğini görmek için kaynağı okuyun.


-3

İstediğiniz verimlilikse command >&-bunun yerine kullanın. Bu, dosya tanımlayıcıyı yeniden yönlendirmek yerine kapatır, bu yüzden ona bir şeyler yazmak için zaman kaybı olmaz.


3
3'ten küçük akışları kapatmayın. Bu std * tanımlayıcılarını rasgele dosya tanımlayıcılarıyla taklit eder; potansiyel olarak felaketle sonuçlanabilir.
Joshua

7
Sadece dosya tanımlayıcıyı kapatırsanız, program her yazma çağrısında hata alır, muhtemelen can sıkıcı hata mesajlarına ve muhtemelen görevini tamamlamadan önce programın sonlanmasına neden olur.
ilkkachu
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.