“|” Linux borusu sembolü ne işe yarar? [çift]


23

İşte bir klasördeki dosyaları ters sırada sıralayan bir komut

ls | sort -r

Bu komuttaki |sembol ne işe yarıyor?

Burada gerçekten aradığım şey Linux yeni başlayanlar için boruların yüksek düzeyde (anlaşılması kolay) açıklamasıdır. Burada Süper Kullanıcı'da borularla ilgili başka sorular görüyorum, ancak basit ifadelerle ne yaptıklarını ve yönlendirmelerden ( >veya <sembollerden) nasıl farklı olduklarını açıklayan bir cevap ortaya çıkaran hiçbir şey göremiyorum .


7
Bunun Linux ile (çekirdeği) alakası yoktur. Genelde borular, girdi / çıktıyı yeniden yönlendirmenin bir yoludur, bash gibi bir kabukta farklı değildir. A ile ilgili özel olan tek şey |bir isim kullanmamasıdır, l-el komutundan çıkan çıktı doğrudan borunun el-tarafındaki komut girişine iletilir.
Andon M. Coleman

Konuyla ilgili tarih dersi için linfo.org/pipe.html
Fredrik Pihl

ls -1r(Bir numaralı argümana dikkat edin) benzer sonuç vermelidir ls | sort -r.
Ivan Chau

Bunu şu şekilde açıklamayı seviyorum: Bir boru bir komutun çıktısını alır ve bir sonraki komut için kullanılabilir hale getirir. Mesela yapabilirsin cat /somefile | grep cool. Bu, bir miktar dosyanın çıktısını alacak ve grep için kullanılabilir hale getirecek ve daha sonra grep tüm satırları içinde serin bir sözcükle basacaktır.
JohnDoea

Yanıtlar:


26

Aşağıdakiler yeni kullanıcılara yardımcı olmak için biraz daha basitleştirilmiştir.

İlk önce standart girdi ve standart çıktı kavramını anlamak gerekir.

Linux ve diğer UNIX benzeri işletim sistemlerinde, her işlemin bir standart girişi ( stdin) ve standart bir çıkışı ( stdout) vardır. Genel durum bu stdinsizin klavyeniz ve stdoutekranınız veya terminal pencerenizdir.

Bu yüzden kaçtığın zaman ls, bunun çıktısını atar stdout. Başka bir şey yapmazsanız, ekranınıza veya terminal pencerenize gider ve siz onu görürsünüz.

Şimdi, bazı Linux komutları kullanıcıyla etkileşime giriyor ve stdinbunu yapmak için kullanıyor ; metin editörünüz bunlardan biri. stdinTuş vuruşlarınızı kabul etmek, bir şeyler yapmak ve ardından bir şeyler yazmak için okur stdout.

Ancak, etkileşimli olarak çalışmayan, ancak bir demet veri isteyen etkileşimli olmayan veya "filtre" komutları da vardır. Bu komutlar herşeye stdinsahip olacak , ona bir şey yapacak ve sonra ona fırlatacakstdout

Diyelim başka bir komuta bakalım du- disk kullanımı için duruyor. du /usrörneğin, ( stdoutdiğer Linux komutlarını beğenmek için), bu dizindeki her dosyanın bir listesini ve boyutunu yazdıracaktır :

# du /usr
2312    /usr/games
124     /usr/lib/tc
692     /usr/lib/rygel-1.0
400     /usr/lib/apt/methods
40      /usr/lib/apt/solvers
444     /usr/lib/apt
6772    /usr/lib/gnash

Hemen yarasadan söyleyebileceğiniz gibi, sıralanmamıştır ve büyüklük sırasına göre sıralanmasını istersiniz.

sortondan bir sürü şey alacak stdinve sıralayacak olan "filtre" komutlarından biridir .

Yani, eğer bunu yaparsak:

# du /usr | sort -nr

Bunu daha iyi anlıyoruz:

4213348 /usr
2070308 /usr/lib
1747764 /usr/share
583668  /usr/lib/vmware
501700  /usr/share/locale
366476  /usr/lib/x86_64-linux-gnu
318660  /usr/lib/libreoffice
295388  /usr/lib/vmware/modules
290376  /usr/lib/vmware/modules/binary
279056  /usr/lib/libreoffice/program
216980  /usr/share/icons

Ve şimdi "boru" nun stdoutbir komutun stdindiğerini diğerine bağladığını görebilirsiniz . Genellikle, komutun çıktısını filtrelemek, sıralamak ya da değiştirmek istediğiniz durumlarda bu gibi durumlarda kullanırsınız. Birden fazla filtre tipi komut aracılığıyla çıktıyı işlemek istiyorsanız bunlar basamaklandırılabilir.

sortKendi kendine yazarsanız , yine de okumaya çalışacaktır stdin. Yana stdinDenetim-D tuşlarına dek yazıp süreç işler için klavyenizin bağlanır, bu bekleyecek. Gerçekten de etkileşimli olarak kullanılmadığı için size bilgi vermeyecektir.

Bir programın stdinetkileşimli olup olmadığını söylemesi mümkündür , bu nedenle bazı programlar bunları kendi başlarına veya bir borunun sonunda yayınlarsanız farklı davranabilir.

Ayrıca, yalnızca etkileşimli olarak çalışan bir programın oluşturulması, vikötü zaman geçirmenize neden olur.

Borular, hiçbir yerde saklanmadan verilerin bir komuttan diğerine karıştırıldığı yönlendirme işleminden farklıdır. Yani, yukarıdaki örnekte, duçıktısı hiçbir yerde saklanmaz. Bunu borularla istemediğiniz zamanların çoğu, çünkü boruları kullanmanın nedeni bir komutun çıktısını bir şekilde işlemektir - ama, teepastanızı almanızı ve yemenizi sağlayan bir komut vardır. stdinikisinden aldıklarını stdoutve seçtiğiniz bir dosyayı kopyalayın . Bunu, bashbilmediğim bir işaret ve köşeli parantez içeren bazı gizli sözdizimi ile de yapabilirsiniz.


Bunun Linux'a, hatta POSIX'e özgü olmadığını unutmayın. Windows kabukları çoğu (hepsi?) De bunu yapar. Ve muhtemelen diğer işletim sistemleri.
Bob,

Ben kavramını biliyorum stdinve stdoutbunun Windows'un açısından büyük bir olasılıkla da pek Linux altında olandan Windows altında farklıdır cmd.exeveya Powershell.
LawrenceC

Ne kadar farklı olduğunu merak ediyorum - açıklar mısın? Yorumlar, bunun için iyi bir yer değilse, belki de sohbette.
Bob,

1
Win32 programları kesinlikle standart bir girdi ve çıktıya sahiptir. Örneğin, işleminizin 'Win32 işleviyle standart girdi, çıktı veya hata tanıtıcısını alabilirsiniz GetStdHandle(). Ayrıca, Win32'nin işlevlerini eşleştirdiğine inandığım, .NET'in standart akışlarının çoğaltılmış bir [alt] işleminin standart akışlarını yeniden yönlendirmesi de önemsizdir (ancak% 100 emin değilim - bir Win32 devi değilim).
Bob,

1
Ah, işte Win32 eşdeğerinde, STARTUPINFOyapı için uygun parametreleri ayarlayarak CreateProcess().
Bob,

27

Çıktı ve giriş yönlendirme konusunda rahatsanız, açıklama gerçekten oldukça kolaydır.

Command1 | Command2

aynısını yapar

Command1 > tempfile
Command2 < tempfile

ama olmadan tempfile. Çıkışı Command1doğrudan girişe bağlanır Command2ve aktarım bellekte gerçekleşir.


Yanılıyor olabilirim ama tempfile'ın sözdiziminde bile var olduğunu düşünüyorum. Sadece bir ismi yok.
Taemyr

3
Hayır değil. Çıktıyı bir komuttan başka bir komutun girişine bağlarken hiçbir dosya sistemi işlemi yapılmaz.
Daniel B,

1
Gerçi, DOS (ve büyük olasılıkla Windows'un) altında, bir geçici dosya olan boru tarafından oluşturulan. Değil * nix, ama hiçbir şey farkı yoktur.
Jeremy J Starcher,

Bunun doğru olmadığından eminim. İşlem İzleme , talebinizi geri almak için hayır CreateFileveya WriteFilearamalar raporlar . / edit: Tabii ki Windows bölümü için.
Daniel B,

3

Gerçekten, boruların ne yaptığını ve> ve | arasındaki farkları bilmek istiyorsanız, o zaman birçok dosya içeren bir dizine gidin ve

Bir terminalden ls vs ls | more (veya yapıyor bu DIR ve DIR ile Windows'tan | FAZLA)

>> Kullandıysanız, ls çıktısını 'more' komutuna göndermek yerine 'more' adında bir dosya oluşturduğunu göreceksiniz. Öyleyse eğer birileri> bir hata yaptıysa, muhtemelen bir hata yapardı, biri yapmazdı> bir şey yapardın> dosya1. Daha çok bilinen bir komuttur.

<Like> komutu ayrıca bir komutu yerine bir komutu ve dosyayı bağlamak için de kullanılır. Ancak> bir komutun çıktısını bir dosyaya gönderirken, <bir dosyayı bir komuta girdi olarak gönderir. Nadiren kullanırım çünkü <genellikle cat file1 kullanırım | | Bir dosyanın çıktısını bir komuta göndermek için.

$ grep a <dosya1 abc

$ kedi dosyası1 | abc aşmak

2 parametresi olan grep, grep pattern dosyasındaki formdur. tek parametreli grep grep desenidir. Ayrıca, dosyanın içeriğini ona bağlayarak ya da <tuşunu kullanarak dosyayı gönderebilirsiniz. <Kullanıyorsanız, önce komut adını, ardından dosya adını <komutundan sonra yazarsınız. Kullanıyorsanız | Bir dosyanın içeriğini yönlendirmek için cat file1 | Komut.

Ayrıca birçok komut yine de girdi olarak bir dosya alır, bu yüzden grep bir dosya1 çalışacaktır, tıpkı cat dosya1 | grep a ve grep a <dosya1.

15 yıl önce bile Borular (|) ve> DOS üzerinde yapıyordum.

Nasıl özetlemek için | <ve> 'dan farklı - Boru 2 komut arasına oturur <ve> komut ile dosya arasına oturur. > Bir dosyaya verilir. <Bir dosyadan girdi.


3

Pipe karakteri ( |), bir programın çıktısını diğerinin girişine bağlar.

Bu örnekte echosözcüğü yazdırır hellove wc -conun bir karakter girdisinde sayarmısın:

echo hello | wc -c

Bir kerede yankı "merhaba \ n" çıkacağını söylemelisin bence. OP'ye çalışmasını söylemiyorsun, bunu cevabını okuyan herkese anlatıyorsun. Neden bu zaman kaybını çarpın?
Rodrigo

Geri bildiriminiz için teşekkürler, cevabımı kısaltdım.
bbaassssiiee

2

Bunu anlamak için kendiniz deneyin:

sort -r

Şimdi bir imleçle takılıyorsun ve hiçbir şey yapmıyor. Bazı verileri girerseniz ne olur?

1
2
3
5
4

Hala bir şey yok değil mi? Şimdi ctrl + D tuşlarına basın

5
4
3
2
1

Yani ne tür bir sıralama, girdi (yazdıklarınız) alır, onunla bir şeyler yapar (sıralar) ve çıktı olarak geri verir. lsKomut sadece çıktısı üretir, giriş almaz. Pipe sembolü çıktıyı alır lsve sortkomuta girdi olarak besler .

>çıktıyı bir programa beslemez, ancak çıktıyı bir dosya olarak saklar. <girdi olarak bir dosya kullanır.

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.