Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Hataları Standart Hataya (Standard Error) Yönlendirmek

Şu anda println! makrosunu kullanarak tüm çıktılarımızı terminale yazıyoruz. Çoğu terminalde iki tür çıktı vardır: Genel bilgiler için standart çıktı (stdout) ve hata mesajları için standart hata (stderr). Bu ayrım, kullanıcıların bir programın başarılı çıktısını bir dosyaya yönlendirmeyi, ancak hata mesajlarını yine de ekrana yazdırmayı seçmesini sağlar.

println! makrosu yalnızca standart çıktıya yazdırma yeteneğine sahiptir, bu yüzden standart hataya yazdırmak için başka bir şey kullanmalıyız.

Hataların Nereye Yazıldığını Kontrol Etmek

İlk olarak, standart hataya yazdırmak istediğimiz hata mesajları da dahil olmak üzere, minigrep tarafından yazdırılan içeriğin şu anda standart çıktıya nasıl yazıldığını gözlemleyelim. Bunu standart çıktı akışını bilerek bir hataya neden olurken bir dosyaya yönlendirerek yapacağız. Standart hata akışını yönlendirmeyeceğiz, bu nedenle standart hataya gönderilen herhangi bir içerik ekranda görüntülenmeye devam edecektir.

Komut satırı programlarının hata mesajlarını standart hata akışına göndermesi beklenir, böylece standart çıktı akışını bir dosyaya yönlendirsek bile hata mesajlarını ekranda görebiliriz. Programımız şu anda iyi davranmıyor: Bunun yerine hata mesajı çıktısını bir dosyaya kaydettiğini görmek üzereyiz!

Bu davranışı göstermek için, programı > ve standart çıktı akışını yönlendirmek istediğimiz ciktilar.txt (output.txt) dosya yolu ile çalıştıracağız. Bir hataya neden olması gereken herhangi bir argümanı iletmeyeceğiz:

$ cargo run > ciktilar.txt

> sözdizimi, kabuğa standart çıktının içeriğini ekran yerine ciktilar.txt dosyasına yazmasını söyler. Ekrana yazdırılmasını beklediğimiz hata mesajını görmedik, bu da mesajın dosyaya gittiği anlamına gelir. ciktilar.txt dosyasının içerdiği şey budur:

Argümanları ayrıştırırken problem oluştu: yeterli argüman yok

Evet, hata mesajımız standart çıktıya yazdırılıyor. Bu gibi hata mesajlarının standart hataya yazdırılması çok daha yararlıdır, böylece dosyaya yalnızca başarılı bir çalıştırmadan elde edilen veriler gider. Bunu değiştireceğiz.

Hataları Standart Hataya (Standard Error) Yazdırmak

Hata mesajlarının yazdırılma şeklini değiştirmek için Liste 12-24’teki kodu kullanacağız. Bu bölümün başlarında yaptığımız yeniden düzenleme nedeniyle, hata mesajlarını yazdıran tüm kodlar tek bir fonksiyonda, yani main içindedir. Standart kütüphane, standart hata akışına yazdıran eprintln! makrosunu sağlar, bu nedenle println! çağırdığımız iki yeri, hata yazdırmak için bunun yerine eprintln! kullanacak şekilde değiştirelim.

Filename: src/main.rs
use std::env;
use std::error::Error;
use std::fs;
use std::process;

use minigrep::{ara, buyuk_kucuk_harf_duyarsiz_ara};

fn main() {
    let argumanlar: Vec<String> = env::args().collect();

    let yapilandirma =
        Yapilandirma::olustur(&argumanlar).unwrap_or_else(|hata| {
            eprintln!("Argümanları ayrıştırırken problem oluştu: {hata}");
            process::exit(1);
        });

    if let Err(e) = calistir(yapilandirma) {
        eprintln!("Uygulama hatası: {e}");
        process::exit(1);
    }
}

pub struct Yapilandirma {
    pub sorgu: String,
    pub dosya_yolu: String,
    pub buyuk_kucuk_harf_yoksay: bool,
}

impl Yapilandirma {
    fn olustur(argumanlar: &[String]) -> Result<Yapilandirma, &'static str> {
        if argumanlar.len() < 3 {
            return Err("yeterli argüman yok");
        }

        let sorgu = argumanlar[1].clone();
        let dosya_yolu = argumanlar[2].clone();

        let buyuk_kucuk_harf_yoksay = env::var("IGNORE_CASE").is_ok();

        Ok(Yapilandirma {
            sorgu,
            dosya_yolu,
            buyuk_kucuk_harf_yoksay,
        })
    }
}

fn calistir(yapilandirma: Yapilandirma) -> Result<(), Box<dyn Error>> {
    let icerik = fs::read_to_string(yapilandirma.dosya_yolu)?;

    let sonuclar = if yapilandirma.buyuk_kucuk_harf_yoksay {
        buyuk_kucuk_harf_duyarsiz_ara(&yapilandirma.sorgu, &icerik)
    } else {
        ara(&yapilandirma.sorgu, &icerik)
    };

    for satir in sonuclar {
        println!("{satir}");
    }

    Ok(())
}
Listing 12-24: eprintln! kullanarak hata mesajlarını standart çıktı yerine standart hataya yazmak

Şimdi programı hiçbir argüman olmadan ve standart çıktıyı > ile yönlendirerek aynı şekilde tekrar çalıştıralım:

$ cargo run > ciktilar.txt
Argümanları ayrıştırırken problem oluştu: yeterli argüman yok

Artık hatayı ekranda görüyoruz ve ciktilar.txt hiçbir şey içermiyor ki bu da komut satırı programlarından beklediğimiz davranıştır.

Hata vermeyen ancak standart çıktıyı yine de aşağıdaki gibi bir dosyaya yönlendiren argümanlarla programı tekrar çalıştıralım:

$ cargo run -- ne siir.txt > ciktilar.txt

Terminalde herhangi bir çıktı görmeyeceğiz ve ciktilar.txt sonuçlarımızı barındıracak:

Dosya adı: ciktilar.txt

Gelme, artık neye yarar?

Bu, uygun olduğu şekilde başarılı çıktılar için standart çıktıyı ve hata çıktıları için standart hatayı kullandığımızı gösterir.

Özet

Bu bölüm, şimdiye kadar öğrendiğiniz bazı önemli kavramları özetledi ve Rust’ta yaygın G/Ç (I/O) işlemlerinin nasıl gerçekleştirileceğini ele aldı. Komut satırı argümanlarını (command line arguments), dosyaları, çevre değişkenlerini (environment variables) ve hataları yazdırmak için eprintln! makrosunu kullanarak, artık komut satırı uygulamaları yazmaya hazırsınız. Önceki bölümlerdeki kavramlarla birleştirildiğinde, kodunuz iyi organize edilmiş olacak, verileri uygun veri yapılarında etkili bir şekilde depolayacak, hataları güzel bir şekilde yönetecek ve iyi test edilmiş olacaktır.

Sırada fonksiyonel dillerden etkilenen bazı Rust özelliklerini inceleyeceğiz: kapanışlar ve yineleyiciler.