Yanıtlar:
cat /dev/null > file.txt
Bir olan kedinin yararsız kullanımı .
Temel olarak cat /dev/null
basitçe cat
hiçbir şeyin çıkmamasıyla sonuçlanır . Evet işe yarıyor, ancak birçok kişi tarafından kaşlarını çattı, çünkü gerekli olmayan bir dış sürecin başlatılmasıyla sonuçlandı.
Bu yaygın olan şeylerden biri, çünkü yaygın.
Sadece > file.txt
çoğu kabuk üzerinde çalışacak, ancak tamamen taşınabilir değil. Tamamen taşınabilir istiyorsanız, aşağıdakiler iyi alternatiflerdir:
true > file.txt
: > file.txt
Hem :
ve true
çıkış hiçbir veri ve (oysa kabuk yerleşiklere vardır cat
, bu yüzden, daha hafif ve daha 'uygun' olan bir dış araçtır).
Güncelleştirme:
Tylerl'in yorumunda belirtildiği gibi, >| file.txt
sözdizimi de var .
Çoğu kabuk, varolan bir dosyayı aracılığıyla kesmelerini önleyen bir ayara sahiptir >
. Bunun >|
yerine kullanmalısın . Bu, gerçekten eklemek istediğinizde insan hatasını önlemek içindir >>
. Davranışı ile ile açabilirsiniz set -C
.
Bu nedenle, bir dosyayı kısaltmanın en basit, en uygun ve taşınabilir yönteminin olacağını düşünüyorum:
:>| file.txt
:
ayrıca POSIX tarafından yerleşik olması için zorunlu kılınır ve aslında "özel" yerleşiktrue
olarak kabul edildiğinden farklıdır .
>| file
daha açık bir kesiktir.
true
yerleşik olması gerekmez ve bunun geleneksel değildi edilir. :
Bourne ailesinin bütün kabukları üzerine inşa edilmiştir. :
POSIX başına özel bir yerleşiktir (bu nedenle : > file
örneğin file
POSIX kabuklarına yazmaya açık değilse kabuktan çıkacaktır ) ve true
değildir. POSIX , bazı sistemlerde olduğundan :
daha verimli olabileceğinden bile bahseder true
.
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
Notlar:
sh
veya ksh
öykünme dışında cat
, komutsuz yönlendirmeler için, zsh'da NULLCMD ve READNULLCMD değişkenleriyle ayarlanabilen varsayılan bir komut kabul edilir (yalnızca stdin yeniden yönlendirmesi için bir çağrı cihazı ). Bu benzer özellikten ilham aldı(t)csh
:
UnixV7'de, :
bir yorum lideri ile bir boş komut arasında yarı yolda yorumlandığı için yönlendirmeler başlangıçta gerçekleştirilmedi . Daha sonra onlar yeniden yönlendirme başarısız olursa, kabuktan çıkan bütün yapıtaşlar için gibiydiler.:
ve eval
yönlendirme başarısız olursa, kabuktan çıkan özel yerleşikler ( bash
yalnızca POSIX modunda yapar).(t)csh
boş bir etiket tanımlamaktadır (for goto
), bu yüzden goto ''
orada dallanırdı. Yeniden yönlendirme başarısız olursa, kabuktan çıkar.$PATH
( :
genellikle değildir; true
, cat
, cp
ve printf
genellikle (POSIX) bunları gerektirir).file
bununla birlikte bir var olmayan bir dosyaya bir sembolik bağdır, bazı cp
GNU en gibi uygulamalar oluşturmak için reddedecektir.(bu bölüm son derece özneldir)
> file
. Bu >
bir bilgi istemi veya yorum gibi görünüyor. Ayrıca bunu okurken soracağım soru (ve çoğu kabukları da aynı şekilde şikayet edecek) tam olarak ne yönlendiriyorsunuz? .: > file
. :
no-op komutu olarak bilinir. Böylece boş bir dosya oluştururken hemen okunur. Bununla birlikte, yine burada, bu :
kolayca kaçırılabilir ve / veya hızlı bir şekilde görülebilir.true > file
: yönlendirme veya dosya içeriği ile ne ilgisi var? Burada ne kastedilmektedir? Bunu okuduğumda aklıma gelen ilk şey.cat /dev/null > file
. Concatenate /dev/null
içine file
? cat
genellikle dosyanın içeriğini dökümü komutu olarak görülüyor, o halen mantıklı olabilir: içeriğini dökümü içine boş dosyadafile
bir dolambaçlı bir yol gibi biraz söylemek, cp /dev/null file
ama yine de anlaşılabilir.cp /dev/null file
. Kopya içeriği boş dosyaya için file
. Mantıklı gelse cp
de, varsayılan olarak nasıl yapılması gerektiğini bilmeyen file
bir kişi null
de bir aygıt yapmaya çalıştığınızı düşünebilir .eval > file
veya eval '' > file
. Hiçbir şey çalıştırmaz ve çıktısını a'ya yönlendirir file
. Bana mantıklı geldi. Ortak bir deyim olmaması garip.printf '' > file
: açıkça bir dosyaya hiçbir şey yazdırmaz . Bana en anlamlı olanı.Aradaki fark, bir kabuk yerleşik kullanıp kullanmamamız olacaktır. Değilse, bir işlem çatallanmalıdır, komut yüklenip çalıştırılmalıdır.
eval
tüm mermilerde inşa edileceği garantilidir. :
bulunduğu her yerde yerleşiktir (Bourne / csh sever). true
sadece Bourne benzeri kabuklarda yerleşiktir.
printf
yerleşik Bourne benzeri kabukları en modern ve fish
.
cp
ve cat
genellikle yerleşik değildir.
Şimdi cp /dev/null file
kabuk yönlendirmelerini çağırmaz, şöyle şeyler:
find . -exec cp /dev/null {} \;
şunlardan daha verimli olacak:
find . -exec sh -c '> "$1"' sh {} \;
(Gerektiğinde mutlaka değil:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
).
Şahsen, : > file
Bourne benzeri mermilerde kullanıyorum ve bugünlerde Bourne benzeri mermilerden başka bir şey kullanmıyorum.
dd of=file count=0
?
dd
(En azından Solaris 10'unki gibi) bazı uygulamaları count=0
ile dikkate alınmaz. dd if=/dev/null of=file
daha taşınabilir olurdu. Her durumda, bu kabuktan bağımsızdır.
cp /dev/null file
, değil mi?
cp /dev/null file
ortak bir deyimdir. Bunları sınırlandırıyorum, mesele mümkün olan tüm yolları listelemek değildir.
Şuna bakmak isteyebilirsiniz truncate
, ki bu da tam olarak şöyle: bir dosyayı kesmek.
Örneğin:
truncate --size 0 file.txt
Bu muhtemelen kullanmaktan daha yavaştır true > file.txt
.
Ancak benim asıl meselem şudur: truncate
dosyaları kesmek için kullanılırken,> kullanımı bir dosyayı kesmenin yan etkisine sahiptir.
truncate
ama hiçbiri mevcut olacaktır >
ne de unistd
C kütüphaneleri mevcut olurdu?
truncate
GNU çekirdek elemanlarına nispeten yakın zamanda (2008) eklenen bir FreeBSD yardımcı programıdır ( --size
GNU uzun seçenek stili GNU’ya özgüdür), bu nedenle GNU dışı veya FreeBSD sistemlerinde mevcut değildir ve eski GNU sistemlerinde mevcut değildir, Taşınabilir olduğunu söyleyemem. cp /dev/null file
Bir kabuk yönlendirme olmadan çalışır ve daha taşınabilir olurdu.
Cevap biraz ne file.txt
olduğuna ve sürecin ona nasıl yazdığına bağlı!
Yaygın bir kullanım durumundan bahsedeceğim: adında büyüyen bir günlük dosyası var file.txt
ve döndürmek istiyorsunuz.
Bu nedenle, örneğin file.txt
içine kopyalar file.txt.save
, sonra keser file.txt
.
Bu senaryoda, eğer dosya açılmazsa another_process
(örneğin: another_process
o dosyayı çıkaran bir program olabilir, örneğin bir şeyi günlüğe kaydeden bir program olabilir), o zaman 2 teklifiniz eşdeğerdir ve her ikisi de iyi çalışır (ancak 2. olarak tercih edilir). ilk "cat / dev / null> file.txt", Yararsız bir Kullanım Kullanımıdır ve ayrıca açar ve / dev / null okur.
Ancak asıl sorun, eğer other_process
hala aktifse ve hala file.txt dosyasına giden açık bir tanıtıcı varsa olacaktır.
Ardından, other process
dosyanın nasıl açıldığına bağlı olarak 2 ana durum ortaya çıkar :
Eğer other_process
normal şekilde açılır, daha sonra kulp hala ofset 1200 bayt örneğin, dosyada eski konuma işaret olacaktır. Bu nedenle bir sonraki yazma 1200 ofset ile başlayacak ve böylece 1200 bitlik boş karakterlerle birlikte yine 1200 byte'lık bir dosya (+ başka bir işlem yazılmadı) olacak! İstediğini değil , sanırım.
Eğer other_process
açılan file.txt
"ekleme modunda", o zaman yazar her zaman, işaretçi aktif dosyanın sonuna çalışılacak. Bu nedenle, kesildiğinde, 0 baytına kadar "arayacak" ve kötü yan etki yaşamayacaksınız! İstediğiniz budur (… genellikle!)
Bunun bir dosyayı kısaltırken, other_process
o konuma hala yazmakta olanların tümünü "ekle" modunda açtığından emin olmak için ihtiyacınız olduğunu unutmayın. Aksi takdirde other_process
, bunları durdurmanız ve yeniden başlatmanız gerekir; bu nedenle eski konum yerine dosyanın başlangıcını işaret etmeye başlarlar.
Kaynaklar: /programming//a/16720582/1841533 daha temiz bir açıklama, normal ve ekleme modu günlük arasındaki farkın güzel bir kısa örneğe için /programming//a/984761/1841533
cat /dev/null > file
ve a arasındaki fark a > file
olup cat /dev/null
, bu dosyada fark yaratmaz.
Bunu beğendim ve sık kullanıyorum çünkü daha temiz görünüyor ve birinin dönüş anahtarına kazayla vurması gibi görünmüyor:
echo -n "" > file.txt
Yerleşik de olmalı mı?
echo
uygulamalar desteklemez -n
(ve çıkış alacaktı -n<SPC><NL>
burada. printf '' > file.txt
) En az çağdaş / POSIX sistemleri arasında (daha taşınabilir olacaktır.