25
Konuya ait anahtar kelimeler : Unix/Linux Redirection of Errors- Hata Yönlendirme Çoğu zaman komutlarımızın sonucunda bir takım hatalar meydana gelebilir. Eğer oluşacak bir hata kullanılmayacak ise yani hata ile bir işimiz yok ise hatalar "/dev/null" sistem aygıtına gönderilmektedir. Bu şekilde herhangi bir hata çıktısı ile karşılaşmayız. Herhangi bir komut için üç parametre sözkonudur: 1- İnput: Girdi. 2- output: Çıktı. 3- errors: Hatalar. Bu parametreler gündelik hayatta da bulunmaktadır. Herhangi bir sistem yada makine için bir girdi, çıktı ve oluşabilecek hatalar bulunmaktadır. Unix/Linux sistemlerde bu parametreleri istediğiniz bir aygıt yada dosyaya gönderebilme hakkınız bulunmaktadır. Eğer bir yönlendirme yapmamışsanız "errors" yani "hatalar" otomatik olarak "/dev/null" aygıtına yönlendirilir. Yönlendirme işlemi, " > " ile olmaktadır. Bu komut aynı zamanda herhangi bir dosya oluşturma komutu olarak ta kullanılmaktadır. Standart çıktıları(output) yönlendirmek için; komut 2> /yönlendirelecek/dosya Standart girdi(input) ve hataları(error) bir dosyaya yönlendirmek için; komut > /yönlendirelecek/dosya 2<&1 örnek kullanımları bulunmaktadır. BASH, bizlere standart çıktıları ve hataları aynı dosyaya yönlendirme imkanını sunmaktadır. Bu işlemi, > Dosya şeklinde yapabiliriz. Yada bu komutun eşiti olan, > Dosya 2>&1 /yönlendirelecek/dosya komut ile yapabiliriz. Bu durumda hatalar ve çıktılar "/dev/null" a gönderilecektir. Hatalarda birer çıktıdır sonuçta. Not : Herhangi bir işlemde hata meydana geldiği zaman hatalar standart çıktıdan kopyalanacaktır. Dosya girdi-çıktı : Eğer sisteminizde "/dev/fd" dizini bulunuyor ise bu klasör içerisinde bazı numaralar göreceksinizdir(0, 1, 2, .. N). Ayrıca sisteminiz "/dev/stdin", "/dev/stdout" ve "/dev/stderr" kullanımını sağlıyorsa bu değerler /dev/fd dizini içerisinde,
  • /dev/stdin : 0
  • /dev/stdout : 1
  • /dev/stderr : 2
sayısal değerlerinde tutuluyor olacaklardır. Yani, /dev/stdin :için "/dev/fd/0" /dev/stdout :için "/dev/fd/1" /dev/stderr :için "/dev/fd/2" ifadelerini kullanabilirsiniz. Şimdi çalışma dizini içerisinde bir kaç örnek yapalım.
[alax@alax ~]$ cdd [alax@alax script]$ ls abcdxyz ls: cannot access abcdxyz: No such file or directory [alax@alax script]$
Örneğimizde "abcdxyz" adında bir dosya/klasör ün listelenmesini sağlamaya çalıştık fakat dizin içerisinde bu isimde bir dosya/klasör olmadığı için "ls: cannot access abcdxyz: No such file or directory" yani "ls:abcdxyz ye ulaşılamıyor: Böyle bir dosya/klasör yok." şeklinde bir hata ile karşılaştık, bu hata aynı zamanda "ls" komutunun da çıktısıdır. Şimdi bu çıktıyı ekranda görmeyelim bir dosyaya yönlendirelim.
[alax@alax ~]$ cdd [alax@alax script]$ ls abcdxyz > hata.txt 2>&1 [alax@alax script]$ cat hata.txt ls: cannot access abcdxyz: No such file or directory [alax@alax script]$
Gördüğünüz gibi oluşan hatayı "hata.txt" dosyasında muhafaza ettik ve ekranda hiçbirşey görülmedi. Eğer çıktı-hata ile bir işimiz yok ise çıktıyı "hata.txt" yerine "/dev/null" a göndermemiz gerekirdi. Önceki derslerimizde ">" ve ">>" arasındaki farkı anlatmıştık. Eğer hataları sürekli bir dosyada toplamak ve önceki hataların silinmemesini isterseniz o zaman ">" yerine ">>" kullanmalısınız. Bu kullanımları zaten biliyor olmalısınız. Diğer şekilde çıktıların gönderildiği adresi "<&" ile çekebilirsiniz. Mesela "/dev/fd/1" çıktılarını "1" den "5" e almak istediğimiz zaman bunu, exec 5<&1 şeklinde gerçekleştiririz. "exec :"Aktif olan işlemi, "exec" komutundan sonraki işlemle değiştirir. Akti olan işlemlere ait Shell i değiştirme de diyebiliriz, Shell ID değeri değişmez.Genel olarak "çalıştır" anlamına gelmektedir. Mesela "perl" programını çalıştırmak için " exec perl ... " şeklinde kullanılır. Şimdilik üzerinde pek durmayacağız. Bu işlem çıktı için, exec fdN> Dosya girdi için, exec fdN< Dosya şeklinde yapılmaktadır. Bu işlemlerin durdurulması için ise, exec fd<&- komutunu kullanabiliriz. En sonda bulunan tire "-" işareti ile işlemin bitirilmesini belirtmekteyiz. Üstteki örneğimiz için iptal işlemi, exec 5<&- şeklinde olacaktır. Bir işlem yapıyoruz ve komutun çıktısının görülmemesini istiyoruz, yani komut çıktısının bizim için bir önemi yok o zaman aşağıdaki gibi bir örnek kullanım ile bunu sağlayabiliriz.
[alax@alax script]$ ls /usr/programlar > /dev/null 2>&1 [alax@alax script]$ ls /usr/programlar 2>/dev/null [alax@alax script]$
Şimdi sistemimizde bulunan programların olduğunu yada olmadığını sorgulayan ve bize hataları saklayarak sunan bir script yazalım. Script verilen pozisyondaki isme göre "which" ile bir sorgulama yapacak ve eğer komut sonucu hata vermez ise programın olduğunu söyleyen mesaj versin aksi halde programın sistemimizde yüklü olmadığını söyleyen bir mesaj versin. "program_kontrol.sh" scriptin adı olsun ve içeriği aşağıdaki olacaktır.
[alax@alax script]$ cat program_kontrol.sh !/bin/bash if [ ! $# -eq 1 ]; then echo "Yanlış kullanım.... Kullanım şekli :\" $0 program_adı \" şeklinde olmaktadır." exit 1 elif (which $1 > /dev/null 2>&1); then echo "$1 programı KURULU..." else echo "$1 programı sisteminizde kurulu DEĞİL..." fi
Yukarıda, "elif (which $1 > /dev/null 2>&1)" ile "which program_adı" komutunun çıktısı "/dev/null" a gönderiliyor ve "2>&1" ile hatalar(error) çıktıya(output) gönderiliyor, eğer son işlem olmuyorsa, yani hatalar çıktıya gönderiliyor ise malum bir hata meydana gelmiştir ve hatalar çıktı ile aynıdır, o halde program kurulu değildir. Bu şekilde yorumlayabiliriz. İkinci olarak, "IF" kullanımında bir durumun olumsuz olma hali sorgulanacak ise durum önüne "!" ünlem işareti getirilir. Bu "durumun sağlanamaması, kontrolün false olarak dönmesi" anlamına gelmektedir. Yukarıda ilk "IF" ile kullanıcının kaç değer yazdığına ve bu değerin bir(1) e eşit olmaması durumuna bakılıyor. if [ $# -eq 1 ] : Pozisyonlardaki değerlerin sayısı 1 e eşit ise. if [ ! $# -eq 1 ] : Pozisyonlardaki değerlerin sayısı 1 e eşit DEĞİL ise. anlamlarına gelmektedir. " > /dev/null 2>&1" bu ifadeyi yorumlayabilirseniz diğer kısımlarıda anlamış olursunuz. komut > /dev/null : Komut çıktısını "/dev/null" a gönder. 2>&1 : Hataları çıktıya gönder, dönüştür. Son olarak yukarıdaki örneğimizde "elif (which $1 > /dev/null 2>&1)" ifadesini "elif [ `which $1 > /dev/null 2>&1` ];" şeklinde de yazabilirdik. Normal parantez kullanıldığı zaman parantezler içerisindeki durum otomatik olarak bir komut olarak algılanır ve çalıştırılır, köşeli parantez ile bunu yapmak için " ` " eğik kesme işareti arasında komutlar yazılmalıdır. Eğik kesme işaretine "AltGr" tuşuna basılı tutarak virgül tuşuna basarak ulaşabilirsiniz. Otomatik cevap, Otomatik yazdırma: Bazen bir komutu çalıştırdığınız zaman sizden bir onay mesajı benzeri bir cevap isteyebilir. Bu gibi durumlarla eminim karşılaşmışsınızdır. Bunları otomatik olarak yapabilirsiniz. Örnek kullanım: komut << herhangi_bir değer1 değer2 değer3 . . değerN herhangi_bir şeklinde olmaktadır. Burada "herhangi_bir" yerine istediğiniz kelimeyi ekleyebilirsiniz, mesela bir onay durumu ise "CONFIRM" yada "ONAY", yada meyve adları ise "meyve_adlari" vb.. . Şimdi örnek yapalım, örneğimizde kullanıcıya 3 adet meyve adını sunalım ve içlerinden birini seçmesini isteyelim. Sonra seçtiği meyve adını "case" ile değerlendirerek ekrana yazdıralım. Script adı "oto.sh" olsun ve içeriği aşağıdaki gibi olacaktır. Bu arada kullanıcının yazdığı cevabıda küçük harfe dönüştürelim.
[alax@alax script]$ cat oto.sh #!/bin/bash # oto.sh cat << meyveler elma muz çilek meyveler echo -n "Lütfen yukarıdaki seçeneklerden sevdiğiniz meyve adını giriniz: " read cevap cevap=${cevap,,} # cevap değişkeni değeri küçük harfe dönüştürülüyor. case $cevap in elma) echo "Hmm elmayı bende severim..." ;; muz) echo "Hmm muzu bende severim..." ;; çilek) echo "Hmm çileği bende severim..." ;; *) echo "Seçenekler arasından bir seçim yapmadınız..." ;; esac [alax@alax script]$
Şimdi scripti çalıştırınız ve sonuçlarını gözlemleyiniz. İleriki derslerimizde, örnekler kısmında bütün konular ile ilgili fazlaca örnek bulacaksınız.