Linux'ta stdin, stdout ve stderr nedir?

stdin, stdoutve stderrbir Linux komutunu başlattığınızda oluşturulan üç veri akışıdır. Komut dosyalarınızın aktarılıp yönlendirilmediğini anlamak için bunları kullanabilirsiniz. Nasıl olduğunu size gösteriyoruz.

Akışlar İki Noktaya Katılıyor

En kısa zamanda Linux ve öğrenmeye başlar başlamaz Unix benzeri işletim sistemleri, terim rastlamak edeceğiz stdin, stdoutve stederr. Bunlar, bir Linux komutu yürütüldüğünde oluşturulan üç standart akıştır. Hesaplamada akış, veri aktarabilen bir şeydir. Bu akışlar durumunda, bu veriler metindir.

Su akışları gibi veri akışlarının iki ucu vardır. Bir kaynakları ve bir çıkışı var. Hangi Linux komutu kullanıyor olursanız olun, her akışın bir ucunu sağlar. Diğer uç, komutu başlatan kabuk tarafından belirlenir. Bu uç, komutu başlatan komut satırına göre terminal penceresine bağlanacak, bir boruya bağlanacak veya bir dosyaya veya başka bir komuta yönlendirilecektir.

Linux Standart Akışları

Linux'ta  stdinstandart giriş akışıdır. Bu, metni girdi olarak kabul eder. Komuttan kabuğa metin çıktısı stdout(standart çıkış) akışı aracılığıyla gönderilir . Komuttaki hata mesajları stderr(standart hata) akışı üzerinden gönderilir .

Yani iki çıkış akışları olduğunu görebilirsiniz stdoutve stderr,, ve bir giriş akışı stdin. Hata mesajları ve normal çıktının her biri, onları terminal penceresine taşımak için kendi kanalına sahip olduğundan, birbirlerinden bağımsız olarak ele alınabilir.

Akışlar Dosyalar Gibi İşlenir

Linux'taki akışlar - hemen hemen her şey gibi - dosyalarmış gibi ele alınır. Bir dosyadan metin okuyabilir ve bir dosyaya metin yazabilirsiniz. Bu eylemlerin her ikisi de bir veri akışı içerir. Dolayısıyla, bir veri akışını bir dosya olarak işleme kavramı o kadar da zor değildir.

Bir işlemle ilişkili her dosyaya, onu tanımlamak için benzersiz bir numara tahsis edilir. Bu, dosya tanımlayıcısı olarak bilinir. Bir dosya üzerinde herhangi bir işlem yapılması gerektiğinde, dosyayı tanımlamak için dosya tanımlayıcı kullanılır.

Bu değerler her zaman için kullanılır stdin, stdout,ve stderr:

  • 0 : stdin
  • 1 : standart çıkış
  • 2 : stderr

Borulara ve Yönlendirmelere Tepki Verme

Bir kişinin bir konuya girişini kolaylaştırmak için yaygın bir teknik, konunun basitleştirilmiş bir versiyonunu öğretmektir. Örneğin, dilbilgisiyle, kuralın "C'den sonra E'den önce I," olduğu söylenir. Ama aslında, bu kuralın, ona uyan durumlardan daha fazla istisnası vardır.

Benzer şekilde, bahsederken stdin, stdoutve stderr bir süreç bilir ne de üç standart akışları sonlandırılır umurunda ne o kabul belitini dışarı tırıs uygundur. Bir süreç çıktısının terminale mi gideceğine mi yoksa bir dosyaya mı yönlendirildiğine dikkat etmeli mi? Girişinin klavyeden mi geldiğini yoksa başka bir işlemden mi aktarıldığını bile anlayabilir mi?

Aslında, bir süreç bilir - veya en azından kontrol etmeyi seçerse öğrenebilir - ve yazılım yazarı bu işlevselliği eklemeye karar verirse davranışını buna göre değiştirebilir.

Bu davranış değişikliğini çok kolay görebiliriz. Şu iki komutu deneyin:

ls

ls | kedi

lsKomut davranır farklı ise çıkış ( stdout) başka bir komut yöneltilen edilmektedir. Bu ise  ls, tek bir sütun çıkışına geçer, bu tarafından gerçekleştirilen bir dönüşüm değildir cat. Ve lsçıkış yönlendirildi olup olmadığını aynı şeyi yapar:

ls> capture.txt

cat capture.txt

Stdout ve stderr yeniden yönlendiriliyor

Ayrılmış bir akış tarafından gönderilen hata mesajlarının bir avantajı vardır. Bu, bir komutun çıktısını ( stdout) bir dosyaya yönlendirebileceğimiz ve yine stderrde terminal penceresinde herhangi bir hata mesajını ( ) görebileceğimiz anlamına gelir . İhtiyaç duyduğunuzda hatalara tepki verebilirsiniz. Ayrıca, hata mesajlarının stdoutiçine yeniden yönlendirilen dosyayı kirletmesini de durdurur .

Aşağıdaki metni bir düzenleyiciye yazın ve error.sh adlı bir dosyaya kaydedin.

#! / bin / bash echo "Varolmayan bir dosyaya erişmeye çalışmak üzere" kedi bozuk-dosyaadı.txt

Komut dosyasını şu komutla çalıştırılabilir hale getirin:

chmod + x error.sh

Betiğin ilk satırı metni stdoutakış yoluyla terminal penceresine yansıtır  . İkinci satır, var olmayan bir dosyaya erişmeye çalışır. Bu, üzerinden teslim edilen bir hata mesajı oluşturacaktır stderr.

Komut dosyasını şu komutla çalıştırın:

./error.sh

Biz de çıkış akışları olduğunu görebilirsiniz, stdoutve stderrterminal pencerelerde görüntülenen edilmiştir.

Çıkışı bir dosyaya yönlendirmeyi deneyelim:

./error.sh> capture.txt

Üzerinden teslim edilen hata mesajı stderrhala terminal penceresine gönderilir. stdout Çıktının dosyaya gidip gitmediğini görmek için dosyanın içeriğini kontrol edebiliriz .

cat capture.txt

Kaynağından alınan çıktı stdinbeklendiği gibi dosyaya yeniden yönlendirildi.

Yeniden >yönlendirme sembolü stdoutvarsayılan olarak çalışır . Yönlendirmek istediğiniz standart çıktı akışını belirtmek için sayısal dosya tanımlayıcılarından birini kullanabilirsiniz.

Açıkça yeniden yönlendirmek  stdoutiçin şu yeniden yönlendirme talimatını kullanın:

1>

Açıkça yeniden yönlendirmek  stderriçin şu yeniden yönlendirme talimatını kullanın:

2>

Testimizi tekrar deneyelim ve bu sefer kullanacağız 2>:

./error.sh 2> capture.txt

Hata mesajı yeniden yönlendirilir ve stdoutechomesaj terminal penceresine gönderilir:

Yakalama.txt dosyasında ne olduğunu görelim.

cat capture.txt

stderrBeklendiği gibi mesaj capture.txt içindedir.

Hem stdout hem de stderr yeniden yönlendiriliyor

Elbette, eğer birini stdoutveya stderrbirbirinden bağımsız olarak bir dosyaya yeniden yönlendirebiliyorsak, ikisini de aynı anda iki farklı dosyaya yönlendirebilmeliyiz?

Evet yapabiliriz. Bu komut, stdoutcapture.txt adlı bir dosyaya ve stderrerror.txt adlı bir dosyaya yönlendirecektir.

./error.sh 1> capture.txt 2> error.txt

Her iki çıktı akışı (standart çıktı ve standart hata) dosyalara yeniden yönlendirildiğinden, terminal penceresinde görünür çıktı yoktur. Hiçbir şey olmamış gibi komut satırı istemine geri dönüyoruz.

Her dosyanın içeriğini kontrol edelim:

cat capture.txt
cat error.txt

Stdout ve stderr'i Aynı Dosyaya Yönlendirme

Bu harika, her bir standart çıktı akışının kendi özel dosyasına gitmesini sağladık. Yapabileceğimiz tek diğer kombinasyon hem göndermektir stdoutve stderraynı dosyaya.

Bunu şu komutla başarabiliriz:

./error.sh> capture.txt 2> & 1

Bunu parçalayalım.

  • ./error.sh : error.sh komut dosyasını başlatır.
  • > capture.txt : stdoutAkışı capture.txt dosyasına yeniden yönlendirir . >kısaltmasıdır 1>.
  • 2> & 1 : Bu, &> yönlendirme talimatını kullanır. Bu talimat, kabuğa bir akışın başka bir akışla aynı hedefe gitmesini söylemenizi sağlar. Bu durumda, "2. akışı, stderrakış 1'in stdoutyönlendirildiği hedefe yönlendir" diyoruz .

Görünür çıktı yok. Bu cesaret verici.

Yakalama.txt dosyasını kontrol edelim ve içinde ne olduğuna bakalım.

cat capture.txt

Hem stdoutve stderrakımları tek hedef dosya yönlendirildi.

Bir akışın çıktısının yeniden yönlendirilmesi ve sessizce atılması için, çıkışı adresine yönlendirin /dev/null.

Komut Dosyası İçinde Yeniden Yönlendirmeyi Algılama

Bir komutun akışlardan herhangi birinin yeniden yönlendirilip yönlendirilmediğini nasıl algılayabileceğini ve davranışını buna göre değiştirmeyi seçebileceğini tartıştık. Bunu kendi senaryolarımızda başarabilir miyiz? Evet yapabiliriz. Anlaması ve uygulaması çok kolay bir tekniktir.

Aşağıdaki metni bir düzenleyiciye yazın ve input.sh olarak kaydedin.

#! / bin / bash eğer [-t 0]; sonra klavyeden gelen yankı stdin başka bir boru veya dosyadan gelen yankı stdin fi

Çalıştırılabilir hale getirmek için aşağıdaki komutu kullanın:

chmod + x input.sh

Akıllı kısım, köşeli parantez içindeki testtir. -t(0) gerçek (terminal) seçeneği döner eğer terminal penceresinde dosya tanıtıcı sona erdiği ile ilişkili dosya. Bunu temsil eden, testin argümanı olarak 0 dosya tanımlayıcısını kullandık   stdin.

Eğer stdinbir terminal penceresinde bağlanır testi doğrudur ispat edecektir. Eğer stdinbir dosya veya bir boruya bağlı olan test başarısız olur.

Komut dosyasına girdi oluşturmak için herhangi bir uygun metin dosyasını kullanabiliriz. Burada dummy.txt adlı bir tane kullanıyoruz.

./input.sh <dummy.txt

Çıktı, komut dosyasının girdinin klavyeden gelmediğini, bir dosyadan geldiğini anladığını gösterir. Seçerseniz, betiğinizin davranışını buna göre değiştirebilirsiniz.

Bu bir dosya yönlendirmeyle oldu, hadi bir boru ile deneyelim.

kedi dummy.txt | ./input.sh

Komut dosyası, girdisinin kendisine iletildiğini tanır. Ya da daha doğrusu, stdinakışın bir terminal penceresine bağlı olmadığını bir kez daha fark eder .

Komut dosyasını ne borularla ne de yönlendirmelerle çalıştıralım.

./input.sh

stdinAkış terminal penceresine bağlı ve komut buna göre bu raporlar edilir.

Aynı şeyi çıktı akışıyla kontrol etmek için yeni bir betiğe ihtiyacımız var. Aşağıdakini bir düzenleyiciye yazın ve output.sh olarak kaydedin.

#! / bin / bash eğer [-t 1]; sonra echo stdout terminal penceresine gidiyor, aksi takdirde echo stdout yeniden yönlendiriliyor veya aktarılıyor fi

Çalıştırılabilir hale getirmek için aşağıdaki komutu kullanın:

chmod + x input.sh

Bu komut dosyasındaki tek önemli değişiklik, köşeli parantez içindeki testtir. Dosya tanımlayıcısını temsil etmek için 1 rakamını kullanıyoruz stdout.

Hadi deneyelim. Çıkışı aktaracağız cat.

./output | kedi

Betik, çıktısının doğrudan bir terminal penceresine gitmediğini tanır.

Çıktıyı bir dosyaya yönlendirerek betiği de test edebiliriz.

./output.sh> capture.txt

Terminal penceresine çıktı yok, sessizce komut istemine geri dönüyoruz. Beklediğimiz gibi.

Neyin yakalandığını görmek için capture.txt dosyasının içine bakabiliriz. Bunu yapmak için aşağıdaki komutu kullanın.

kedi capture.sh

Yine, betiğimizdeki basit test, stdoutakışın doğrudan bir terminal penceresine gönderilmediğini tespit eder .

Komut dosyasını herhangi bir kanal veya yeniden yönlendirme olmadan çalıştırırsak, bunun stdoutdoğrudan terminal penceresine teslim edildiğini algılaması gerekir .

./output.sh

Ve bu tam olarak gördüğümüz şey.

Bilinç Akışı

Komut dosyalarınızın terminal penceresine veya bir boruya bağlı olup olmadığını veya yeniden yönlendirilip yönlendirilmediğini nasıl anlayacağınızı bilmek, davranışlarını buna göre ayarlamanıza olanak tanır.

Günlüğe kaydetme ve tanılama çıktısı, ekrana mı yoksa bir dosyaya mı gittiğine bağlı olarak az veya çok ayrıntılı olabilir. Hata mesajları, normal program çıktısından farklı bir dosyaya kaydedilebilir.

Genelde olduğu gibi, daha fazla bilgi daha fazla seçenek getirir.