Linux'ta stdin, stdout ve stderr nedir?
stdin
, stdout
ve stderr
bir 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
, stdout
ve 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 stdin
standart 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 stdout
ve 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
, stdout
ve 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
ls
Komut 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 stderr
de 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 stdout
iç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 stdout
akış 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, stdout
ve stderr
terminal pencerelerde görüntülenen edilmiştir.
Çıkışı bir dosyaya yönlendirmeyi deneyelim:
./error.sh> capture.txt
Üzerinden teslim edilen hata mesajı stderr
hala 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ı stdin
beklendiği gibi dosyaya yeniden yönlendirildi.
Yeniden >
yönlendirme sembolü stdout
varsayı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 stdout
için şu yeniden yönlendirme talimatını kullanın:
1>
Açıkça yeniden yönlendirmek stderr
iç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 stdout
echo
mesaj terminal penceresine gönderilir:
Yakalama.txt dosyasında ne olduğunu görelim.
cat capture.txt
stderr
Beklendiği gibi mesaj capture.txt içindedir.
Hem stdout hem de stderr yeniden yönlendiriliyor
Elbette, eğer birini stdout
veya stderr
birbirinden bağımsız olarak bir dosyaya yeniden yönlendirebiliyorsak, ikisini de aynı anda iki farklı dosyaya yönlendirebilmeliyiz?
Evet yapabiliriz. Bu komut, stdout
capture.txt adlı bir dosyaya ve stderr
error.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 stdout
ve stderr
aynı 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 :
stdout
Akışı capture.txt dosyasına yeniden yönlendirir .>
kısaltmasıdır1>
. - 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ışı,
stderr
akış 1'instdout
yö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 stdout
ve stderr
akı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 stdin
bir terminal penceresinde bağlanır testi doğrudur ispat edecektir. Eğer stdin
bir 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, stdin
akışı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
stdin
Akış 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, stdout
akışı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 stdout
doğ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.