Linux'ta stdin, stdout ve stderr nedir?

Yayınlanan: 2022-01-29
Linux bilgisayarda terminal penceresi
Fatmawati Achmad Zaenuri/Shutterstock.com

stdin , stdout ve stderr , bir Linux komutu başlattığınızda oluşturulan üç veri akışıdır. Komut dosyalarınızın yönlendirilip yönlendirilmediğini anlamak için bunları kullanabilirsiniz. Size nasıl olduğunu gösteriyoruz.

Akışlar İki Noktayı Birleştiriyor

Linux ve Unix benzeri işletim sistemleri hakkında bilgi edinmeye başlar başlamaz stdin , stdout ve stederr terimleriyle karşılaşacaksınız. Bunlar, bir Linux komutu yürütüldüğünde oluşturulan üç standart akıştır. Bilgi işlemde akış, veri aktarabilen bir şeydir. Bu akışlar söz konusu olduğunda, bu veriler metindir.

Su akışları gibi veri akışlarının iki ucu vardır. Bir kaynağı ve bir çıkışı var. Hangi Linux komutunu kullanırsanız kullanın, 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 stdin , standart girdi akışıdır. Bu, metni girdi olarak kabul eder. Komuttan kabuğa metin çıktısı, stdout (standart çıkış) akışı aracılığıyla iletilir. Komuttan gelen hata mesajları, stderr (standart hata) akışı aracılığıyla gönderilir.

Böylece, stdout ve stderr olmak üzere iki çıkış akışı ve bir giriş akışı, stdin olduğunu görebilirsiniz. Hata mesajları ve normal çıktıların her birinin onları terminal penceresine taşımak için kendi kanalı olduğundan, birbirlerinden bağımsız olarak işlenebilirler.

Akışlar Dosyalar Gibi İşlenir

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

Reklamcılık

Bir işlemle ilişkili her dosyaya, onu tanımlamak için benzersiz bir numara atanır. Bu, dosya tanımlayıcı olarak bilinir. Bir dosya üzerinde bir eylemin gerçekleştirilmesi gerektiğinde, dosyayı tanımlamak için dosya tanımlayıcısı kullanılır.

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

  • 0 : standart
  • 1 : standart
  • 2 : standart

Borulara ve Yönlendirmelere Tepki Verme

Birinin bir konuya girişini kolaylaştırmak için yaygın bir teknik, konunun basitleştirilmiş bir versiyonunu öğretmektir. Örneğin, dilbilgisi ile 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 bir şekilde, stdin , stdout ve stderr hakkında konuşurken, bir işlemin üç standart akışının nerede sonlandırıldığını bilmediği veya umursamadığı kabul edilen aksiyomu ortaya çıkarmak uygundur. Bir süreç çıktısının uçbirime mi yoksa bir dosyaya mı yönlendirildiğine mi dikkat etmeli? Girişinin klavyeden mi geldiğini yoksa başka bir işlemden mi aktarıldığını bile söyleyebilir mi?

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

Reklamcılık

Davranıştaki bu değişikliği çok kolay görebiliriz. Bu iki komutu deneyin:

 ls 

 l | kedi 

ls komutu, çıktısı ( stdout ) başka bir komuta aktarılıyorsa farklı davranır. Tek sütun çıktısına geçiş yapan ls , cat tarafından gerçekleştirilen bir dönüştürme değildir. Ve çıktısı yönlendiriliyorsa ls aynı şeyi yapar:

 ls > yakalama.txt 

 kedi yakalama.txt 

stdout ve stderr'yi yeniden yönlendirme

Özel bir akış tarafından iletilen hata mesajlarına sahip olmanın bir avantajı vardır. Bu, bir komutun çıktısını ( stdout ) bir dosyaya yeniden yönlendirebileceğimiz ve yine de terminal penceresinde herhangi bir hata mesajı ( stderr ) görebileceğimiz anlamına gelir. Gerektiğinde hatalara oluştukları anda tepki verebilirsiniz. Ayrıca, stdout yeniden yönlendirildiği dosyayı kirleten hata mesajlarını da durdurur.

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

 #!/bin/bash

echo "Var olmayan bir dosyaya erişmeye çalışmak üzere"
cat kötü dosyaadı.txt

Komut dosyasını bu komutla yürütülebilir yapın:

 chmod +x hatası.sh

Komut dosyasının ilk satırı, metni stdout akışı aracılığıyla terminal penceresine yansıtır. İkinci satır, var olmayan bir dosyaya erişmeye çalışır. Bu, stderr aracılığıyla iletilen bir hata mesajı oluşturacaktır.

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

 ./hata.sh 

Terminal pencerelerinde her iki çıktı akışının ( stdout ve stderr ) görüntülendiğini görebiliriz.

Çıktıyı bir dosyaya yönlendirmeyi deneyelim:

 ./error.sh > yakalama.txt 

Reklamcılık

stderr aracılığıyla iletilen hata mesajı hala terminal penceresine gönderilir. stdout çıktısının dosyaya gidip gitmediğini görmek için dosyanın içeriğini kontrol edebiliriz.

 kedi yakalama.txt 

stdin gelen çıktı, beklendiği gibi dosyaya yönlendirildi.

> yeniden yönlendirme sembolü, varsayılan olarak stdout ile çalışır. Hangi standart çıktı akışını yeniden yönlendirmek istediğinizi belirtmek için sayısal dosya tanımlayıcılarından birini kullanabilirsiniz.

stdout açıkça yeniden yönlendirmek için bu yeniden yönlendirme talimatını kullanın:

 1>

stderr açıkça yeniden yönlendirmek için bu yeniden yönlendirme talimatını kullanın:

 2>

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

 ./error.sh 2> yakalama.txt 

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

Capture.txt dosyasında neler varmış bir bakalım.

 kedi yakalama.txt 

stderr mesajı, beklendiği gibi yakalama.txt dosyasında.

Hem stdout hem de stderr Yönlendirme

Elbette, stdout veya stderr birbirinden bağımsız olarak bir dosyaya yönlendirebilirsek, ikisini de aynı anda iki farklı dosyaya yönlendirebilmemiz gerekir mi?

Reklamcılık

Evet yapabiliriz. Bu komut, stdout yakalama.txt adlı bir dosyaya ve stderr error.txt adlı bir dosyaya yönlendirecektir.

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

Standart çıktı ve standart hata çıktılarının her iki akışı da dosyalara 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:

 kedi yakalama.txt
 kedi hatası.txt 

Stdout ve stderr'i Aynı Dosyaya Yönlendirme

Çok güzel, standart çıktı akışlarının her birinin kendi özel dosyasına gitmesine sahibiz. Yapabileceğimiz diğer kombinasyon, hem stdout hem de stderr aynı dosyaya göndermektir.

Bunu aşağıdaki komutla başarabiliriz:

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

Bunu parçalayalım.

  • ./error.sh : error.sh komut dosyasını başlatır.
  • > yakalama.txt : stdout akışını yakalama.txt dosyasına yönlendirir. > 1> 'in kısaltmasıdır.
  • 2>&1 : Bu, &> yönlendirme talimatını kullanır. Bu talimat, kabuğa bir akışın başka bir akışla aynı hedefe ulaşmasını söylemenizi sağlar. Bu durumda, "akım 2'yi, stderr , akış 1'in, stdout yönlendirildiği aynı hedefe yönlendirin" diyoruz.

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

Capture.txt dosyasını kontrol edelim ve içinde ne olduğunu görelim.

 kedi yakalama.txt 

Hem stdout hem de stderr akışları tek bir hedef dosyaya yönlendirildi.

Bir akışın çıktısının yeniden yönlendirilmesini ve sessizce atılmasını sağlamak için çıktıyı /dev/null yönlendirin.

Bir Komut Dosyasında 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. Ve anlaşılması ve uygulanması çok kolay bir tekniktir.

Reklamcılık

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 borudan veya bir dosyadan gelen yankı stdin
 
fi

Yürütülebilir hale getirmek için aşağıdaki komutu kullanın:

 chmod +x girdi.sh

Akıllı kısım, köşeli parantez içindeki testtir. -t (uçbirim) seçeneği, dosya tanıtıcıyla ilişkili dosya uçbirim penceresinde sonlanırsa doğru (0) değerini döndürür. Testin argümanı olarak stdin temsil eden dosya tanıtıcı 0'ı kullandık.

Eğer stdin bir terminal penceresine bağlıysa, test doğru olacaktır. stdin bir dosyaya veya boruya bağlanırsa, test başarısız olur.

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

 ./input.sh < kukla.txt 

Çıktı, komut dosyasının girdinin klavyeden değil, bir dosyadan geldiğini tanıdığını gösterir. Seçtiyseniz, komut dosyanızın davranışını buna göre değiştirebilirsiniz.

Reklamcılık

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

 kedi kukla.txt | ./input.sh 

Komut dosyası, girdisinin kendisine aktarıldığını tanır. Veya daha doğrusu, stdin akışının bir terminal penceresine bağlı olmadığını bir kez daha tanır.

Komut dosyasını ne borular ne de yönlendirmeler olmadan çalıştıralım.

 ./input.sh 

stdin akışı, terminal penceresine bağlanır ve komut dosyası bunu buna göre bildirir.

Aynı şeyi çıktı akışıyla kontrol etmek için yeni bir komut dosyasına 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
 
Başka

echo stdout yeniden yönlendiriliyor veya yönlendiriliyor
 
fi

Yürütülebilir hale getirmek için aşağıdaki komutu kullanın:

 chmod +x girdi.sh

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

Deneyelim. Çıktıyı cat aracılığıyla ileteceğiz.

 ./çıktı | kedi 

Reklamcılık

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

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

 ./output.sh > yakalama.txt 

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

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

 kedi yakalama.sh 

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

Reklamcılık

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

 ./output.sh 

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

Bilinç Akışları

Komut dosyalarınızın terminal penceresine mi yoksa bir boruya mı bağlı olduğunu veya yeniden yönlendirildiğ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 ç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çeneği beraberinde getirir.

İLGİLİ: Geliştiriciler ve Meraklılar için En İyi Linux Dizüstü Bilgisayarlar