`>` Ve `>>` nasıl çalışır?


9

revBir dosyaya denedim ve sonra boruya geçtim cat > same_fileama boş bir dosyaya dönüşüyordu.

Denediğimde rev file.txt | cat > file2.txt && mv file.txt file2.txt;işe yaradı.

Hatta rev file.txt | cat >> file.txt;çalıştı.

Ama denediğimde rev file.txt | cat > file.txtbaşarısız oldu.


Da bırakabilirsiniz catbu gibi dışarı: rev file.txt > file2.txt && mv file2.txt file.txt. Bu gereksiz bir kullanımdırcat . Dışarıda bırakarak, ekstra bir süreç yumurtlamaya yedek.
matega

Yanıtlar:


19

Bu durumda her iki yönlendirme yöntemi (> ve >>) arasında kavramanız gereken temel şey:

>

Yönlendirildiği bilgileri yönlendirir ve üzerine yazar . Bu, "|" borusundan herhangi bir bilgi alınırken olur

>>

Yönlendirildiği bilgileri yönlendirir ve birleştirir . Bu, "|" borusundan herhangi bir bilgi alınırken olur

Her iki durumda da dosya yoksa, dosya oluşturulur. Aynı dosya üzerinde tekrar çalıştırırsanız, bilgiler yalnızca ">>" üzerinde birleştirilir. ">" İle ilk çalıştırmada yaptığınız her şeyin üzerine yazabilirsiniz.

Ancak çıktı dosyasıyla aynı girdi dosyasını kullanırken yapılan anlaşma. Bu durumda, ">" kullanırsanız, çıktı dosyasının "üzerine yazacağı" için "giriş" kısmının ayrıştırılması gereken bilgileri kaldırırsınız. Yani:

rev file.txt | cat > file.txt

"Ağır çekim açıklaması" nda gerçekte olan şey:

  1. reviçeriğini tersine çevirmeye file.txtve boruya göndermeye hazırlar
  2. İken revboruya bilgi gönderdiğinden, boru doğrudan akışları cat.
  3. İken catbilgilerini alıyorsa otomatik olarak uygulayacaktır file.txtonunla kuruldu.
  4. Buradaki anahtar kelime "while" şeklindedir, çünkü her şey aynı anda gerçekleşmektedir. Bu bölümde daha derin bir anlayışa sahip olmak için lütfen Emil'in aşağıdaki mükemmel yorumlarına bakın.
  5. catrevtüm dosyanın oluşturulmasını beklemez . Bilgilerin ilk kısmının kendisine ulaştığı andan itibaren başlayacak, yani kullandığınız sembole bağlı olarak bir bağlantı açılacaktır file.txt.
  6. Bu durumda >> yerine > kullanıldığından, kabuk çıktı dosyasını keser, bu da yeni bilgilerin ulaşmasını beklerken bilgilerini açıp temizleyeceği anlamına gelir . >> ile bir bağlantı açar ve algılanan son satırdaki yeni bilgileri bekler.file.txtfile.txt
  7. Bilgiler zaten içinde aklandı yana file.txtolan > , rev's işi yapmak ve çünkü hiçbir şey elde etmeye çalışacağını catyeni bilgiler için hazırlık silinen herşey.

Peki diğerleri yukarıdakileri okuduktan sonra neden çalışıyor? Bu nedenle:

rev file.txt | cat > file2.txt && mv file.txt file2.txt

Burada, bilgiyi başka bir dosyaya gönderen kediye pipetleme yapıyorsunuz . Bu durumda, işlenen girdi dosyası file.txtçıktı dosyası ile aynı değildir file2.txt. Kelimenin tam anlamıyla bütün üzerine yazıyorsunuz Bundan sonra file2.txtbirlikte file.txtyapılan tüm süreç böylece, catsilindi. Temelde tüm satır basitleştirilebilir cp file.txt file2.txtçünkü aynı şeyi yapıyor çünkü file2.txtsonunda kaybediyor revve mvkomutla üzerine yazılıyor .

rev file.txt | cat >> file.txt

Bu durumda , bilgileri aynı dosyayla birleştirirsiniz . Bu yüzden sadece o dosyaya bir bağlantı açıyor, ancak tek bir > ile görüldüğü gibi bilgileri silmiyor . Sonuç, orijinal bilgiler artı tersine çevrilmiş bilgiler olmalıdır.


5
Dosya kedi tarafından kesilmez. Boru hattındaki komutlardan herhangi biri başlamadan önce kabuk tarafından kesilir .
Emil Jeřábek

Doğru, açıklanması kolay kelimeler arıyordu. OP'nin ne bir kabuk olduğunu ve tüm bunları bilmediğini açıklamak biraz zor olduğundan. Mümkün olduğunca "dost" yapmaya çalışıyorum.
Luis Alvarado

1
Aslında, kabuk tarafından yapıldığı önemli değil, ama sunduğunuz zamanlamanın yanlış olması. Kesme işlemi 6. adımda gerçekleşmeyecek, ancak 0. adımda rev file.txt | cat --bogus-option > file.txtkedi de açmaya çalışmasa da dosyayı kesecektir.
Emil Jeřábek

@ EmilJeřábek haklısın. Yine de nasıl davrandığını bilmeyen kullanıcılar, sadece komutlarla adım adım gidersek daha kolay olacaktır. Ayrıca örneğiniz bilgileri hala aynı dosyaya gönderiyor, bu yüzden bash tüm satırı okuyacak, çıktıyı görecek ve hala açacak ve kesecek. Hata stdout çıktı stderr basitçe.
Luis Alvarado

4
Ayrıca bkz moreutils , (aynı paket deposundan temin araçlar fantastik bir koleksiyon moreutilsiçerir) sponge, özellikle bir giriş dosyası üzerine yazmak USECASE tasarlanmış bir araçtır. Örneğin, rev file.txt >file2.txt && mv file2.txt file.txtgeçici bir çözüm olur ve rev file.txt | sponge file.txtzaten adlandırılmış bir şey olsa bile düzgün çalışır file2.txt.
Daniel Wagner

9

Kabuk yeniden yönlendirme gördüğünde, ilgili komutlardan herhangi birini yürütmeden önce ilgili dosyaları açar. Böylece, yaptığınız zaman:

foo file.txt | bar > file.txt

Daha öncefile.txt kısaltılmasına neden olan yönlendirme çalıştırılır ve okunabilir . Yan notta, bu yüzden yapamazsınız: foofile.txt

sed 'blah' file.txt > file.txt

Ve neden sedyerinde düzenleme seçeneği var?

Son olarak:

.. | cat > file.txt

olan kedinin bir işe yaramaz kullanımı sen okuma denemesinde, özellikle eğer öyleyse, file.txtdaha erken.

Bir dosyayı yerinde ters çevirmek istiyorsanız, kısayol yoktur . Yerinde düzenleme ile sedveya awkpüf noktalarını kullanabilirsiniz .


3

>çıktıyı başka bir şeye gönderen bir yönlendirici (operatör)
(bir sonraki komutun girişi, yazıcı ..)

Sizin durumunuzda çıktı bir dosyaya gider file.txt, eğer bu dosya zaten mevcutsa, üzerine yazılır, eğer oluşturulmamışsa.

>>bir ekleme operatörüdür, file.txtzaten varsa çıktı dosyanın sonuna eklenir. dosya yoksa, oluşturulur ve çıktı >(yeniden yönlendirici) ile aynı şekilde yeni dosyaya yazılır .


OP bunu anlamış görünüyor. Karışıklık her iki tarafında olmak Aynı dosyadan sadece kaynaklanıyor gibi görünüyor >ve >>operatörler.
bzlm

0

Vim'i Ex modunda kullanabilirsiniz:

ex -sc '%!rev' -cx file.txt
  1. % tüm satırları seç

  2. ! komutu çalıştır

  3. x kaydet ve kapat

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.