<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//TR">
<HTML>
<HEAD>
 <META http-equiv="Content-Type" content="text/html; charset=iso-8859-9">
 <META NAME="GENERATOR" CONTENT="lfparser_2.17">
 <META NAME="LFCATEGORY" CONTENT="UNIX Basics">
<!-- this is used be a number of tools:
 =LF=AUTHOR: Katja and Guido     Socher
 =LF=CAT___: UNIX Basics
 =LF=TITLE_: Kabuk Programlama
 =LF=NUMBER: 216
 =LF=ANAME_: article216.shtml
 -->
 <TITLE>lf216, UNIX Basics: Kabuk Programlama</TITLE>
<!-- stylesheet added by lfparser: --> 
<style type="text/css">
<!--
 td.top {font-family: Arial,Geneva,Verdana,Helvetica,sans-serif; font-size:12 }
 pre { font-familiy:monospace,Courier }
 p.cl { color:#EE9500 }
 a.nodec { text-decoration:none }
 p.trans { font-size:8pt; text-align:right }
 p.clbox { width:50%; alignment:center; background-color:#FFD700; border-style:none; border-width:medium; border-color:#FFD700; padding:0.5cm ;  text-align:center }
 p.foot { background-color:#AAAAAA; color:#FFFFFF; border-style:none; border-width:medium; border-color:#AAAAAA; padding:0.5cm ; margin-top:0.1cm; margin-right:1cm; margin-left:1cm; text-align:center }
-->
</style>
 
</HEAD>
<BODY bgcolor="#ffffff" text="#000000">
 <!-- this is generated html code. NEVER use this file for your
 translation work. Instead get the file with the same article number
 and .meta.shtml in its name. Translate this meta file and then
 use lfparser program to generate the final article -->
 <!-- lfparser can be obtained from http://www.linuxfocus.org/~guido/dev/lfparser.html -->

<!-- 2pdaIgnoreStart -->

<!-- start navegation bar -->
 <!-- top navegation bar -->
 <TABLE cellspacing="0" cellpadding="0" border="0" align="center" width="90%">
   <TR bgcolor="#2e2292">
     <TD class="top"><TABLE cellspacing="0" cellpadding="0" border="0" width=
       "100%">
         <TR><TD width="144"><IMG src="../../common/images/logolftop.gif"
           alt="[LinuxFocus-icon]" width="350" height="45" align="left" 
           border="0"></TD>

           <TD class="top">
             <TABLE width="100%">
               <TR align="right">
                 <TD class="top"><A class="nodec" href="../index.shtml"><FONT color=
                 "#DDDDDD">Ev</FONT></A> &nbsp;|&nbsp; <A class=
                 "nodec" href="../map.html"><FONT color=
                 "#DDDDDD">Erişimdüzeni</FONT></A> &nbsp;|&nbsp; <A class=
                 "nodec" href="../indice.html"><FONT color=
                 "#DDDDDD">İçindekiler</FONT></A> &nbsp;|&nbsp; <A class="nodec" href="../Search/index.shtml"><FONT color=
                 "#DDDDDD">Arama</FONT></A> </TD>
               </TR>

               <TR align="right">
                 <TD class="top">
                   <HR width="100%" noshade size="1">
                 </TD>
               </TR>
             </TABLE>
           </TD>
         </TR>
       </TABLE>
     </TD>
   </TR>
 </TABLE>
 <!-- end top navegation bar -->
 <!-- blue bar -->
 <TABLE cellspacing="0" cellpadding="0" border="0" align="center"
 width="90%">
   <TR bgcolor="#00ffff">
     <TD><IMG src="../../common/images/transpix.gif" width="1" height=
     "2" alt=""></TD>
   </TR>
 </TABLE>
 <!-- end blue bar -->
 <!-- bottom navegation bar -->
 <TABLE cellspacing="0" cellpadding="0" border="0" align="center"
 width="94%">
   <TR bgcolor="#000000">
     <TD>
       <TABLE cellspacing="0" cellpadding="1" border="0" width=
       "100%">
         <TR align="center">
           <TD><A class="nodec" href="../News/index.html"><FONT color=
           "#FFFFFF">Duyumlar</FONT></A> </TD>
           <TD><FONT color="#FFFFFF">|</FONT> </TD>
           <TD><A class="nodec" href="../Archives/index.html"><FONT color=
           "#FFFFFF">Belgelikler</FONT></A> </TD>
           <TD><FONT color="#FFFFFF">|</FONT> </TD>
           <TD><A class="nodec" href="../Links/index.html"><FONT color=
           "#FFFFFF">Bağlantılar</FONT></A> </TD>
           <TD><FONT color="#FFFFFF">|</FONT> </TD>
           <TD><A class="nodec" href="../aboutus.html"><FONT color=
           "#FFFFFF">LF Nedir</FONT></A> </TD>
         </TR>
       </TABLE>
     </TD>
   </TR>
 </TABLE>
 <!-- end bottom navegation bar -->
<!-- stop navegation bar -->

<!-- SSI_INFO -->

<!-- tr_staticssi include virtual -->
<!-- tr_staticssi exec cmd -->
<!-- addedByLfdynahead ver 1.1 --><TABLE ALIGN="right" border=0><TR><TD ALIGN="right"><FONT SIZE="-1" FACE="Arial,Helvetica">Bu makalenin farklı dillerde bulunduğu adresler: <A href="../../English/September2001/article216.shtml">English</a> &nbsp;<A href="../../Castellano/September2001/article216.shtml">Castellano</a> &nbsp;<A href="../../Deutsch/September2001/article216.shtml">Deutsch</a> &nbsp;<A href="../../Francais/September2001/article216.shtml">Francais</a> &nbsp;<A href="../../Nederlands/September2001/article216.shtml">Nederlands</a> &nbsp;<A href="../../Portugues/September2001/article216.shtml">Portugues</a> &nbsp;<A href="../../Turkce/September2001/article216.shtml">Turkce</a> &nbsp;</FONT></TD></TR></TABLE><br>
 

<!-- 2pdaIgnoreStop -->

<!-- SHORT BIO ABOUT THE AUTHOR -->
<TABLE ALIGN=LEFT BORDER=0 hspace=4 vspace=4 WIDTH="30%" >
<TR>
<TD>

<!-- 2pdaIgnoreStart -->
<!-- PALM DOC -->
<TABLE BORDER=0 hspace=4 vspace=4> <TR> <TD>
<font size=1> <img src="../../common/images/2doc.gif" width=34 align=left border=0 height=22 alt="convert to palm"><a href="http://cgi.linuxfocus.org/cgi-bin/2ztxt">Convert to GutenPalm</a><br>or <a href="http://cgi.linuxfocus.org/cgi-bin/2pda">to PalmDoc</a></font>
</TD> </TR> </TABLE>
<!-- END PALM DOC -->
<!-- 2pdaIgnoreStop -->
<br>
<IMG src="../../common/images/KatjaAndGuido.jpg" alt=
    "[Photo of the Authors]" height="150" width="168">
<BR>tarafından  <A href=     "mailto:katja&#64;linuxfocusorg, guido@linuxfocus.org">Katja and Guido     Socher</A>
<BR><BR>
<I>Yazar hakkında:</I><BR>
<P>
	Katja LinuxFocus'un Alman editörüdür. Tux, film,
	fotografçılığı ve denizi sever.
	Ana sayfasına <A href="http://www.toppoint.de/~utuxfan/k/">buradan ulaşabiliriz</A>.
	</P><P>
	Guido uzun zamandan beri bir Linux hayranı ve Linux'u dürüst ve açık insanlar tarafından tasarlandığı için seviyor.
	İşte bu ona açık kodlu dememizin bir nedeni...  Guido'nun sanaldoku sayfası:
	<A href="http://main.linuxfocus.org/~guido/">linuxfocus.org/~guido</A></P>
<BR><i>İçerik</i>:
<UL>
  <LI><A HREF="#216lfindex0">Neden kabuk programlama ?</A></LI>
  <LI><A HREF="#216lfindex1">Betiğin oluşturulması</A></LI>
  <LI><A HREF="#216lfindex2">Yorumlar</A></LI>
  <LI><A HREF="#216lfindex3">Değişkenler</A></LI>
  <LI><A HREF="#216lfindex4">Kabuk komutları ve denetim yapıları</A></LI>
  <LI><A HREF="#216lfindex5">Örnekler</A></LI>
  <LI><A HREF="#216lfindex6">Hata ayıklama</A></LI>
  <LI><A HREF="#216lfindex7">Kaynaklar</A></LI>
  <LI><A HREF="http://cgi.linuxfocus.org/cgi-bin/lftalkback?anum=216&lang=en">Bu yazı için görüş bildiriminde bulunabilirsiniz</A></LI>
</UL>

</TD></TR></TABLE>
<!-- HEAD OF THE ARTICLE -->
<br>&nbsp;
<H2>Kabuk Programlama</H2>
 <IMG src="../../common/images/illustration216.jpg" width="199"
    height="150" alt="[Illustration]" hspace="10">
<!-- ABSTRACT OF THE ARTICLE -->
<h3>Çeviri : Ceyhun ELMAS ve Erdal MUTLU</h3>
<P><i>Özet</i>:
<P>

    Bu yazıda küçük bir kabuk betiğinin nasıl yazılacağı pek çok örnekle veriliyor.

    </P>
<HR size="2" noshade align="right"><BR>
<!-- BODY OF THE ARTICLE -->


    <A NAME="216lfindex0">&nbsp;</A>
<H2>Neden kabuk programlama ?</H2>

    Linux için çok çeşitli grafiksel arayüzler sağlansa bile kabuk henüz en düzgün araçtır.
   Kabuk yalnızca bir komutlar yığını değil aynı zamanda çok iyi bir programlama dilidir.
   Pek çok işlemi bununla otomatik olarak yapabilirsiniz, özellikle sistem yönetimiyle ilgili konularda çok iyidir,
   Eğer tasarımınız doğruysa hemen deneyebilir ve kullanışlı basit prototipler oluşturabilirsiniz.
   Verimliliğin yapılandırmanın, bakımın ve uyumun kolaylığından daha az önemli olduğu basit işlemli küçük uygulamalar
   için çok kullanışlıdır.
   <BR>
     Haydi nasıl çalıştığına bakalım: <BR>


    <A NAME="216lfindex1">&nbsp;</A>
<H2>Betiğin oluşturulması</H2>

    Linux için pek çok kabuk bulunmaktadır fakat genellikle kabuk programlama için,
    ücretsiz ve kulanımı kolay olan
    bash (bourne again shell) kullanılır.
    Dolayısıyla bu yazıdaki tüm betikleri bash kullanarak yazdık (ancak zamanın çoğunda bu yaşlı kızkardeş bourne kabuğu
    ile koşacak).<BR>
     Kabuk programlarımızı yazmak için her çeşit metin editörü kullanabiliriz,
     örneğin, nedit, kedit, emacs, vi... diğer programlama dillerinde olduğu gibi.<BR>
     Program aşağıdaki satırla başlamalıdır.(bu , dosyadaki ilk satır olmalıdır):<BR>

<PRE>
    #!/bin/sh

</PRE>
    The #! karakterleri sisteme, bu karakterleri takip eden argumanın bu dosyayı çalıştırmakta kullanacağını söyler.
    Burada kullandığımız kabuk /bin/sh 'dır.<BR>
     Bir betik yazdığınızda ve bunu kayıt ettiğinizde bu betiği kullanabilmek için çalıştırılabilir yapmalısınız.
     <BR>
     Betiği bu şekilde çalıştırılabilir yapın:<BR>
     chmod +x filename <BR>
     Sonra betiği <TT>./filename</TT> komutuyla çalıştırabilirsiniz. <BR>


    <A NAME="216lfindex2">&nbsp;</A>
<H2>Yorumlar</H2>

    Betik programlarında yorumlar # ile başlar ve satırın sonuna kadar gider.
    Biz gerçekten yorum kullanmanızı öneriyoruz. Eğer betik içine yorumlar koyarsanız
    bu betiğe gereksinim duyduğunuz zamanlarda ne yaptığını ve nasıl çalıştığını
    zaman kaybetmeden anlamış olacaksınız.
    <BR>


    <A NAME="216lfindex3">&nbsp;</A>
<H2>Değişkenler</H2>

    Diğer programlama dillerinde değişkenler olmadan yaşayamazsınız.
    Betik programlarında tüm değişkenler veritipi dizgisine sahiptir ve
    bunları yayınlama. Değişkene değer atamak şöyle olur:
<PRE>
degisken=deger
</PRE>
    Değeri görmek için değişkenin önüne dolar işareti koymak yeterlidir:
<PRE>
#!/bin/sh
# Bir değer ata:
a="Merhaba Dünya"
# Şimdi "a" nın değerini yaz:
echo "a nın değeri:"
echo $a
</PRE>
    Bu satırları metin editörünüzde yazın ve "first" ismiyle kayıt edin.
    Sonra chmod +x komutuyla betiği çalıştırılabilir yapın ve ./first komutuyla
    çalıştırın. <BR>
    Betiğin çıktısı böyle olacaktır :
<PRE>
a nın değeri:
Merhaba Dünya
</PRE>
    Bazen bu durum yazının diğer kısımlarıyla değişken isimlerinin
 karışmasına yol açabilir.

<PRE>
num=2
echo "this is the $numnd"
</PRE>
    Bu "this is the 2nd" yazmayacaktır.Çıktı : "this is the " olacaktır.
    Çünkü betik numnd adı verilen değişkeni arayacak ve bir değere sahip olmadığını
    bulacaktır. Burada parantezleri kullanırsak :
<PRE>
num=2
echo "this is the ${num}nd"
</PRE>
    Bu istediğimizi yazacaktır: this is the 2nd <BR>
    <BR>
    Burada değişkenlerin sayısı herzaman otomatik olarak belirlenir
    Bunları ilk kullanışımızda tekrar ele alacağız.
    <BR>
    <BR>
     Eğer matematiksel ifadelere gereksiniminiz varsa
     expr gibi programlar kullanmalısınız (aşagıdaki tabloda görünüyor).
     <BR>
     Ayrıca betikte geçerli olan değişkenler aynı zamanda çevre değişkenleridir.
    Değişken açkısözcük tarafından önce alınır , çevre değişkenleri ihraç edilir.
    Bunlardan burada daha fazla sözetmeyeceğiz. Bunlar normalde yalnızca sistemgiriş
    betiklerinde kullanılır.

    <A NAME="216lfindex4">&nbsp;</A>
<H2>Kabuk komutları ve denetim yapıları</H2>

    Kabuk betiklerinde kullanılacak üç sınıf komut vardır: <BR>
     <BR>
     <B>1)Unix komutları:</B><BR>
     Kabuk betiklerinde her Unix komutunun kullanılabilmesine karşın,
     diğerlerine göre daha fazla kullanımı olan komutlar vardır.
     Bu komutlar genellkle dosya ve metin işlemleri ile ilgilidir.
    <BR>

    <TABLE bgcolor="#aaaaff" border="1" align="center">
      <TR>
        <TH width="30%">Komut kullanımı (syntax)</TH>

        <TH>Amaç</TH>
      </TR>

      <TR>
        <TD>echo "metin kısmı"</TD>

        <TD>Metin kısmını ekrana yazar.</TD>
      </TR>

      <TR>
        <TD>ls</TD>

        <TD>Dosyaları listeler.</TD>
      </TR>

      <TR>
        <TD>wc -l dosya<BR>
        wc -w dosya<BR>
        wc -c dosya</TD>

        <TD>Dosyadaki stırları sayar veya<BR>
          sözcükleri veya<BR>
         karatkterleri sayar.</TD>
      </TR>

      <TR>
        <TD>cp kaynakdosya hedefdosya</TD>

        <TD>Kaynakdosya'yı hedefdosya olarak kopyalar.</TD>
      </TR>

      <TR>
        <TD>mv eskiad yeniad</TD>

        <TD>Dosya adını değiştirir veya dosyayı taşır.</TD>
      </TR>

      <TR>
        <TD>rm dosya</TD>

        <TD>Dosya siler.</TD>
      </TR>

      <TR>
        <TD>grep 'katar' dosya</TD>

        <TD>Dosya içerisinde katar arar.<BR>
        Örnek: grep 'aranacak katar' dosya.txt</TD>
      </TR>

      <TR>
        <TD>cut -b sütün dosya</TD>

        <TD>Sabit uzunluklu metin sütünlarından veri elde etme.<BR>
        Örnek: 5 ile 9 arasındaki karakterleri elde eder.<BR>
        cut -b5-9 dosya.txt<BR>
        Bu komutu bam başka bir komut olan  "cat" ile karıştırmayın.
        </TD>
      </TR>

      <TR>
        <TD>cat dosya.txt</TD>

        <TD>dosya.txt'yi standart çıktı aygıtına yazar (sizin ekranınız).</TD>
      </TR>

      <TR>
        <TD>file dosya</TD>

        <TD>Dosyanın tipi hakkında bilgi vermektedir.</TD>
      </TR>

      <TR>
        <TD>read değişken</TD>

        <TD>Kullanıcıdan aldığı değeri değişken'e yazar.
        </TD>
      </TR>

      <TR>
        <TD>sort dosya.txt</TD>

        <TD>dosya.txt'daki satırları sıralar(dizer).</TD>
      </TR>

      <TR>
        <TD>uniq</TD>

        <TD>Tekrarlanan satırları siler. Sadece arka arkaya gelen ve tekrarlanan
        satırları sildiği için sort ile birlikte kullanılabilir. <BR>
        Örnek: sort dosya.txt | uniq<BR>
        </TD>
      </TR>

      <TR>
        <TD>expr</TD>

        <TD>Kabuk içerisinde matematiksel işlemler yapar.<BR>
        Örnek:  2 ile 3 toplamak için<BR>
        expr 2 "+" 3</TD>
      </TR>

      <TR>
        <TD>find</TD>

        <TD>Dosya araması yapar.<BR>
        Örnek: dosya ismine göre arama:<BR>
        find . -name dosyaismi -print<BR>
        Aslında bu komutun birçok kullanımı vardır ve hepsini bu yazıda anlatmak ne yazık ki
        olası değildir.
        </TD>
      </TR>

      <TR>
        <TD>tee</TD>
        Standart çıktı aygıtına (sizin ekranınız) veri yazmak. Genellikle
        şu şekilde kullanılır:<BR>
        herhangikomut | tee çıktıdosyası<BR>
        Komutun çıktısını ekrana ve dosyaya yazar.
        </TD>
      </TR>

      <TR>
        <TD>basename dosya</TD>

        <TD>Yoltanımı(dizin) kısmını atarak sadece dosyanın adını üretir.
        <BR>
        Örnek: basename /bin/tux<BR>
        Sadece tux elde edilir.</TD>
      </TR>

      <TR>
        <TD>dirname dosya</TD>

        <TD>
        Dosya adınını atarak sadece yoltanımını (dizin) üretir.
        <BR>
        Örnek: dirname /bin/tux<BR>
        Sadece /bin kısmı elde edilir.</TD>
      </TR>

      <TR>
        <TD>head dosya</TD>

        <TD>Dosya başından itibaren birkaç satır yazar.</TD>
      </TR>

      <TR>
        <TD>tail dosya</TD>

        <TD>Dosya sonundan itibaren birkaç satır yazar.</TD>
      </TR>

      <TR>
        <TD>sed</TD>

        <TD>sed basit olarak bul ve değiştir programıdır.
        Ekrandan (veya borudan) okuduğu metinleri standart
        çıktı aygıtına (genelde ekran) yazar.
        Aranan metin düzenli ifadedir (kaynaklar
        kısmına bakınız). linuxfocus katarını LinuxFocus ile değiştirmek için :<BR>
        cat metin.dosyası | sed 's/linuxfocus/LinuxFocus/' &gt;
        yenimetin.dosyası<BR>
        kullanabilirsiniz. Bu her satırdaki linuxfocus'ları LinuxFocus ile değiştirir.
        Eğer, aynı satırda birden fazla linuxfocus varsa, sadece ilkini değiştirir.
        Bir satırdan birden fazla aynı ifadeden varsa ve siz bunu değiştirmek istiyorsanız:<BR>
        cat metin.dosyası | sed 's/linuxfocus/LinuxFocus/g' &gt;
        yenimetin.dosyası<BR>
        </TD>
      </TR>

      <TR>
        <TD>awk</TD>

        <TD>
          Genellikle awk bir satırdaki alanları elde etmek için kullanılmaktadır.
          Benimsenmiş değer olarak, alan ayracı, boşluk karakteridir. Başka bir
          alan ayracı belirtmek için -F seçeneği kullanılabilir.
<PRE>
 <SMALL>cat dosya.txt | awk -F, '{print $1 "," $3 }'
</SMALL>
</PRE>
          Burada ayraç olarak virgül (,) karakteri kullanıldı ve ilk ve üçüncü ($1 $3)
          alanlar (sütünlar) elde edildi. Eğer, dosya.txt'nin satırları şu şekilde ise:
<PRE>
<SMALL>Adam Bor, 34, India
Kerry Miller, 22, USA
</SMALL>
</PRE>
          o zaman sonuç:
<PRE>
<SMALL>Adam Bor, India
Kerry Miller, USA
</SMALL>
</PRE>
          olur. Awk ile bundan çok daha fazlasını yapmak olasıdır. Bu sadece en çok
          kullanılan şeklidir.
        </TD>
      </TR>
    </TABLE>
    <BR>
    <BR>
     <B>2) Kavramlar: Borular, yönlendirme ve ters tırnak</B><BR>
     Bunlar gerçekte komut, ancak aynı zamanda da çok önemli kavramlardır. <BR>
<BR>
     <B>Borular</B> (|) bir programın çıktısını (stdout) başka bir programın girdisi
     olarak vermektedir (stdin).<BR>
<PRE>
    grep "merhaba" dosya.txt | wc -l
</PRE>
    dosya.txt dosyasındaki merhaba kelimesini içeren satırları bulmakta ve onları saymaktadır.<BR>
    Grep komutunun çıktısı wc komutuna girdi olarak kullanılmıştır. Belli mantık sınırları
    içerisinde bu şekilde istediğiniz kadar komutu, borular ile arka arkaya kullanabilirsiniz.<BR>
    <BR>
     <B>Yönlendirme</B>: bir komutun çıktısını bir dosyaya yazmaktadır veya dosyanın arkasına
     eklemektedir.<BR>
     &gt; çıktıyı bir dosyaya yazmaktadır. Eğer, dosya varsa, dosyanın üzerine yazmaktadır.<BR>
     &gt;&gt; çıktıyı dosyanın arkasına eklemektedir (Dosya yoksa, yeni bir dosya
     yaratarak içerisine yazmaktadır, ancak hiçbir zaman dosya üzerine yazmamaktadır.).<BR>
    <BR>
     <B>Ters tırnak</B><BR>
     Bir komutun çıktısı başka bir komuta parametre olarak (Bu yukarıdaki
     standart girdi (stdin) aygıtı gibi değildir, program isminden sonra verilen
     katarlar parametreleri oluşturmaktadır.) verilebilir.
     Ayrıca, bir programın çıktısını bir değişkene atamak için
     de kullanılabilir.<BR>
<PRE>
find . -mtime -1 -type f -print
</PRE>
    Komutu, 24 saat içerisinde değiştirilmiş tüm dosyaları bulmaktadır.
     (-mtime -2 ise, 48 saat olura). Eğer, bütün bu dosyaları bir tar dosyası
    (dosya.tar) haline getirmek istiyorsanız :
<PRE>
tar xvf dosya.tar dosya1 dosya2 ...
</PRE>
    Tüm dosyaları tek tek yazmaktansa, iki (find ve tar) komutu ters tırnak
    kullanarak birleştirebiliriz. Böylece, tar komutu, find komutunun bulduğu tüm
    dosyaları paketleyecektir:
<PRE>
#!/bin/sh
# Tırnaklar ters tırnaktır (`),  normal tırnak değil ('):
tar -zcvf ensondegisen.tar.gz `find . -mtime -1 -type f -print`
</PRE>
    <BR>
     <B>3) Denetim yapıları</B><BR>
    <B>"if" ifadesi</B> bir ifadenin doğru olup olmadığını denetlemektedir
    (Çıkış durum bilgisi 0 ise, başarılı demektir). Eğer, doğru ise "then" kısmı
    çalıştırılmaktadır:
<PRE>
if ....; then
   ....
elif ....; then
   ....
else
   ....
fi
</PRE>
    Genelde, if ifadesi, içerisinde test adı verilen bir komut kullanılmaktadır.
    Bu komut katar karşılaştırılmasında, dosyanın var olup olmadığının denetlenmesinde,
    dosyanın okuma hakkı olup olmadığını denetlenmesinde ... kullanılmaktadır.<BR>
    "test" komutu " [ ] " köşeli parantezler olarak yazılmaktadır. Burada kullanılan
    boşluklar önemlidir : Parantezlerden önce ve sonra boşluk olmasına dikkat ediniz.
    Örnek:
<PRE>
[ -f "dosya" ]     : "dosya" nın dosya olup olmadığını denetler.
[ -x "/bin/ls" ]   : /bin/ls çalıştırılabilir bir dosya olup olmadığını denetler.
[ -n "$değisken" ] : $degisken'in herhangi bir değer taşıyıp taşımadığını
                     denetlemektedir.
[ "$a" = "$b" ]    : "$a" nın  "$b" ye eşit olup olmadığını denetlemektedir.
</PRE>
    "man test" komutunu çalıştırarak, tüm karşılaştırma ve dosya
    denetleme seçeneklerini elde edeceksiniz.<BR>
    Bu kabuk programını kullanmak oldukça basittir:
<PRE>
#!/bin/sh
if [ "$SHELL" = "/bin/bash" ]; then
  echo "Giriş kabuğunuz bash (bourne again shell) dır."
else
  echo "Giriş kabuğunuz bash değil $SHELL dir"
fi
</PRE>
    $SHELL değişkeni kullanılan kabuğun ismini içermektedir ve biz onu
    "/bin/bash" ile karşılaştırıyoruz.<BR>
    <BR>
    <B>Kısayol işlemcileri (operatörleri)</B><BR>
    C ile tanışık olan kişiler aşağıdaki yapıyı hemen benimseyeceklerdir:<BR>
<PRE>
[ -f "/etc/shadow" ] &amp;&amp; echo "Bu bilgisayar gölge şifrelemesi
                                      (shadow passwords) kullanıyor."
</PRE>
    &amp;&amp; ifadesi if-ifadesine kısayol gibi kullanılabilir.
    İfadenin sağ tarafı ancak sol tarafı doğru olduğunda çalıştırılmaktadır.
    Bunu VE (AND) gibi okuyabilirsiniz. Buna göre : "/etc/shadow dosyası
    var VE echo çalıştırılmaktadır". VEYA (||) işlemcisi de vardır. Örnek:
<PRE>
#!/bin/sh
eiletidizini=/var/spool/mail/james
[ -r "$eiletidizini" ] || { echo "$eiletidizini dizinini okuyamıyorum" ; exit 1; }
echo "$eiletidizini de eiletiniz var.:"
grep "^From " $eiletidizini
</PRE>
    Bu kabuk betiği e-ileti dizinini okuyup okuyamadığna bakmaktadır.
    Eğer, okuyabiliyorsa, dosyadan "From" içeren satırları ekrana yazmaktadır.
    Eğer $eiletidizini dosyasını okuyamıyorsa, VEYA işlemcisi devreye girmektedir.
    Normal İngilizce'de program parçasını şu şekilde okuyoruz: "E-ileti dizini okunabilir
    veya çık.". Buradaki sorun, VEYA'dan sonra sadece bir komuta yer olmasıdır, ancak bizim birden
    fazla komuta gereksinimiz vardır:
    <BR>
    -hata mesajı görüntüle <BR>
    -programdan çık <BR>
    Bu ikisini bir arada kullanabilmek için, bunları adı olmayan bir fonksiyon
    olarak grupluyoruz. Fonksiyonlar hakkında genel bilgi aşağıda verilmektedir.
    <BR>
    Herşeyi VE veya VEYA'lar kullanmadan, sadece if-ifadelerinden yararlanarak da gerçekleştirebilirsiniz,
    VE ve VEYA'lar biraz daha kullanışlıdır.
    <BR>
    <BR>
    <B>case</B> ifadesi bir katarı (kabuktaki * ve ? de kullanılabilir) birden fazla seçenekten birine uygun düşürmede kullanılmaktadır.
<PRE>
case ... in
...) burada birşeyler yap;;
esac
</PRE>
    Bir örnek ele alalım. Bir dosyanın tipini fıle komutunu kullanarak öğrenebiliriz:
<PRE>
file lf.gz

sonuç:

lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix
</PRE>
    Şimdi biz bu komutu <A href="../../common/src/article216/smartzip.txt">smartzip</A> adında, otomatik
    olarak sıkıştırılmış (uncompress, bzip2, gzip ve zip) dosyaları açan bir kabuk programı yazımında kullanacağız:
<PRE>
#!/bin/sh
ftype=`file "$1"`
case "$ftype" in
"$1: Zip archive"*)
    unzip "$1" ;;
"$1: gzip compressed"*)
    gunzip "$1" ;;
"$1: bzip2 compressed"*)
    bunzip2 "$1" ;;
*) error "File $1 dosyası smartzip ile açılamıyor.";;
esac
</PRE>
    <BR>
    Eğer, dikkat ettiyseniz, burada özel bir değişken kullandık $1. Bu değişken,
    programa komut satırından verilen ilk parametreyi içermektedir. Programı :
    <BR>
    smartzip yazilar.zip <BR>
    gibi çalıştırırsak, $1'in alacağı değer yazilar.zip olacaktır.
    <BR>
    <BR>
    <B>select</B> ifadesi bash kabuğuna özgüdür ve etkileşimli kullanımlarda
    oldukça yarar sağlamaktadır. Kullanıcı, kendisine verilen bir listeden birini
    seçebilmektedir:
<PRE>
select var in ... ; do
  break
done
.... şimdi $var kullanılabilir ....
</PRE>
    İşte örnek:
<PRE>
#!/bin/sh
echo "En favori işletim sisteminiz hangisidir?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Diğer"; do
        break
done
echo "Seçiminiz $var dur."
</PRE>
    Kabuk programı şunları gerçekleştirmektedir:
<PRE>
En favori işletim sisteminiz hangisidir?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Diğer
#? 1
Seçiminiz Linux dur."
</PRE>
    Kabukta kullanabileceğiniz <B>döngü ifadeleri</B> şunlardır:
<PRE>
while ...; do
 ....
done
</PRE>

    <B>while-döngüsü</B> denetlenen ifade doğru olduğu sürece
    çalışılacaktır. Döngünün herhangi bir noktasından çıkmak için
    "break" kullanılabilir. Döngünün herhangi bir yerinde "continue"
    kullanılırsa, döngünün geriye kalanı çalıştırılmamakta ve onun yerine
    döngünün başına dönülmektedir.
    <BR>
    <BR>
    <B>for-döngüsü</B> boşluklar ile ayrılmış
    katar listesini parametre olarak almaktadır ve bunları sırasıyla
    ilgili değişkene atamaktadır:
<PRE>
for değişken in ....; do
  ....
done
</PRE>
    Aşağıdaki örnekte A dan C'ye kadar olan karakterler ekrana yazmaktadır:
<PRE>
#!/bin/sh
for degisken in A B C ; do
  echo "değişkenin değeri $degisken"
done
</PRE>
    Aşağıda daha kullanışlı bir örnek yer almaktdadır. Örnek,
    rpmgoster adını taşımakta ve parametre olarak verilen  rpm
    paketleri hakkında bilgi elde etmekte ve ekranda göstermektedir:
<PRE>
#!/bin/sh
# RPM paketlerinin içeriğini listeler
# KULLANIM: rpmgoster rpmdosya1 rpmdosya2 ...
# ÖRNEK: rpmgoster /cdrom/RedHat/RPMS/*.rpm
for rpmpaketi in $*; do
  if [ -r "$rpmpaketi" ];then
    echo "=============== $rpmpaketi =============="
    rpm -qi -p $rpmpaketi
  else
    echo "HATA: $rpmpaketi dosyası okunamadı."
  fi
done
</PRE>
    Yukarıdaki örnekte komut satırından verilen ve tüm parametreleri içeren
    $* değişkenini görüyorsunuz. Programı, <BR>
    rpmgoster openssh.rpm w3m.rpm webgrep.rpm<BR>
    olarak çalıştırırsak, $* değişkeni 3 parametreyi birlikte içerecektir:
    openssh.rpm, w3m.rpm ve webgrep.rpm. <BR>
    <BR>
     GNU bash ayrıca until-döngüsüne de sahiptir, ancak while ve for
    döngüleri genellikle yeterli olmaktadır.
    <BR>
    <BR>
     <B>Tırnak içine alma</B><BR>
    Programa herhangi bir parametre göndermeden önce, kabuk
    joker (*, ?) karakterleri ve değişkenleri kullanmaya ve yerleştirmeye
    çalışmaktadır. Kullanmak ve yerleştirmeden kasıt, joker (*, ? gibi)
    karakterlerin yerine uygun dosya adları konulması ve değişkenlerin yerine
    taşıdıkları değerler ile değiştirilmesidir. Bu uygulamayı değiştirmek için
    tırnak kullanabilirsiniz: Sözgelimi, bulunduğumuz dizinde yer alan dosyalar
    arasında eileti.jpg ve tux.jpg jpg dosyaları da olsun.
<PRE>
#!/bin/sh
echo *.jpg
</PRE>
    Bu ekrana "eileti.jpg tux.jpg" yazacaktır.<BR>
    Bunu önlemek için tek veya çift tırnak kullanabiliriz:
<PRE>
#!/bin/sh
echo "*.jpg"
echo '*.jpg'
</PRE>
    Bu ise, ekrana "*.jpg" ifadesini iki kez yazmaktadır. <BR>
    Tek tırnaklar daha kısıtlayıcıdır. Tek tırnak kullanıldığında,
    değikenlerin yerine değerlerinin konulması bile engellenmektedir:
<PRE>
#!/bin/sh
echo $SHELL
echo "$SHELL"
echo '$SHELL'
</PRE>
    Sonuç aşağıdaki gibi olacaktır:
<PRE>
/bin/bash
/bin/bash
$SHELL
</PRE>
    Son olarak, özel anlam taşıyan herhangi bir karakteri yazmak için önüne ters
    bölü çizgisi kullanabiliriz:
<PRE>
echo \*.jpg
echo \$SHELL
</PRE>
    dolayısıyla:
<PRE>
*.jpg
$SHELL
</PRE>
    elde edilir.<BR><BR>

    <B>Bilgilendirme yeri</B><BR>
    Bilgilendirme yeri, birden fazla satırdan oluşan metni bir komuta
    göndermek istediğinizde kullanılabilir. Kabuk programlarınızda
    yardım metni yazarken her satırın başına echo komutunu kullanmadan yazabilmek
    oldukça kullanışlı olmaktadır. "Bilgilendirme yeri" &lt;&lt; ve metnin
    sonunda da yazılması gereken bir başlık ile başlamaktadır.
    <A href="../../common/src/article216/ren.txt"> ren adındaki örnek
    kabuk programı</A>, yardım metni için bilgilendirme yerinden faydalanmaktadır
    ve yaptığı iş ise, birden fazla dosya ismini değiştirmmektir:
<PRE>
#!/bin/sh
# Eğer, 3'ten daha az paramtre verilmişse, yardım mesajı görüntülenecektir:
if [ $# -lt 3 ] ; then
cat &lt;&lt;YARDIM
ren -- birden fazla dosyanın adını sıradan ifadeler kullanarak değiştirmektedir.

KULLANIMI: ren 'sıradanifade' 'yerinekonulacakifade' dosyalar...

ÖRNEK: tüm *.HTM dosyalarını *.html olarak değiştirmek için:
  ren 'HTM$' 'html' *.HTM

YARDIM
  exit 0
fi
ESKI="$1"
YENI="$2"
# shift komutu, komut satırından verilen parametre listesinden
# bir adet parametreyi silmektedir
shift
shift
# Şimdi $* tüm dosyaları içermektedir:
for dosya in $*; do
    if [ -f "$dosya" ] ; then
      yenidosya=`echo "$dosya" | sed "s/${ESKI}/${YENI}/g"`
      if [ -f "$yenidosya" ]; then
        echo "HATA: $yenidosya zaten var"
      else
        echo "$dosya sı $yenidosya olarak değiştirilmektedir ..."
        mv "$dosya" "$yenidosya"
      fi
    fi
done
</PRE>
    Bu şu ana kadar incelediğimiz en karmaşık betiktir. Bunun üzerinde biraz
    konuşalım. İlk if-ifadesi, komut satırından verilen parametre
    sayısının en azından 3 adet olup olmadığını denetlemektedir.
    (Özel bir değişken olan $# de parametre sayısını tutmaktadır.)
    Eğer, parametre sayısı yeterli değil ise, yardım mesajı cat komutuna,
    o da ekrana göndermektedir. Yardım mesajı görüntülendikten sonra programdan
    çıkılmaktadır. Eğer, 3 veya daha fazla parametre verilmiş ise, ilki ESKI,
    ikincisi de YENI değişkenlerine atanmaktadır. Daha sonra, shift komutu iki defa kullanılarak
    3. paramtreyi ilk parametre olarak elde etmek için kaydırılmaktadır.
    $* daki her parametre tek tek $dosya değişkenine atanmaktadır.
    İlk önce dosyanın var olup olmadığı denetlenmektedir ve ondan sonra
    yeni dosya adı eskisi üzerinde sed komutuyla yapılan değiştirme
    ile elde edilmektedir. Ters tırnaklar, yeni dosya isminin yenidosya değişkenine atamak
    için kullanılmıştır. Artık gereksinim duyduğumuz herşeye sahibiz: eski dosya
    adına ve yenisine. Bu ikisi mv komutuna parametre olarak verilerek,
    eski dosya ismi yenisi ile değiştirilmektedir.
    <BR>
    <BR>
     <B>Fonksiyonlar</B><BR>
    Daha karışık programlar yazmaya başlar başlamaz, aynı program
    parçalarını birden fazla yerde kullandığınızı fark ediyorsunuz. Bunun
    için fonksiyonlardan yararlanabiliriz. Bir fonksiyon aşağıdaki gibi
    gözükmektedir:
<PRE>
fonksiyonismi()
{
 # Fonksiyon gövdesinde (içerisnde) $1, fonksiyona verilen ilk parametre
 # $2 ikinci vs.
 fonksiyonun gövdesi
}
</PRE>
    Fonksiyonu kullanmadan önce, programın başında fonksiyonu "tanımlamak"
    gerekmektedir.
    <BR>
    <BR>
    Konsole penceresinin başlığını değiştirmek için
    <A href="../../common/src/article216/xtitlebar.txt">xtitlebar</A> adlı
    program kullanılabilir. Eğer, aynı anda birden fazla konsole kullanıyorsanız,
    başlıklarından hangisinin ne olduğunu kolayca anlayabilirsiniz.
    Konsole'un ismi, kendisine gönderilen kaçış kodu (escape sequence)
    ile değiştirilmektedir. Betik yardim adinda bir fonksiyon kullanmaktadır.
    Görüldüğü üzere, yardim fonksiyonu bir defa tanımlanmış ve iki yerde
    kullanılmıştır:
<PRE>
#!/bin/sh
# vim: set sw=4 ts=4 et:

yardim()
{
    cat &lt;&lt;YARDIM
xtitlebar -- xterm, gnome-terminal veya kde konsole un adı değiştirir.

KULLANIMI: xtitlebar [-h] "başlık"

SEÇENEKLER: -h yardim metin

ÖRNEK: xtitlebar "cvs"

YARDIM
    exit 0
}

# Hata durumunda veya -h parametresi verildiğinde yardim
# fonksiyonunu çağırmaktayız:
[ -z "$1" ] &amp;&amp; yardim
[ "$1" = "-h" ] &amp;&amp; yardim

# konsole'un başlığını değiştirmek için kaçış kodu gönder:
echo -e "\033]0;$1\007"
#
</PRE>
    Yazdığınız programlarda geniş yardım bilgilerine yer vermeniz
    iyi bir alışkanlıktır. Bu size ve başkalarına programı kullanırken
    oldukça faydalı olmaktadır.
    <BR>
    <BR>
     <B>Komut satırı parametreleri</B><BR>
    $* ve $1, $2 ... $9 komut satırından verilen parametreleri (programın adından sonra
    gelen veriler) içerdiklerini görmüştük. Şu ana kadar az sayıda ve oldukça basit yapıda
    parametre kullandık (Bir iki gerekli parametre ve -h yardım için).
    Ancak, çok geçmeden, komut satırından verilen parametreleri işleyecek
    bir işlemciye gereksinim duyacaksınız. Genelde, seçime bağlı tüm parametrelerin başı
    eksi işaretini koymak ve bunların diğer parametrelerden (dosya adı vs.)
    önce gelmesi alışılagelmiş bir uygulamadır. <BR>
    <BR>
    Parametre işlemcisi oluşturmanın birçok yolu vardır. Aşağıdaki
    while döngüsü ve case ifadesi
     <A href="../../common/src/article216/cmdparser.txt">
    genel bir parametre işlemci</A> için çok uygun bir çözümdür:
<PRE>
#!/bin/sh
yardim()
{
  cat &lt;&lt;YARDIM
Bu genel bir parametre işlemcisidir.
ÖRNEK KULLANIM: cmdparser -l merhaba -f -- -dosya1 dosya2
YARDIM
  exit 0
}

while [ -n "$1" ]; do
case $1 in
    -h) yardim;shift 1;; # yardım fonksiyonu çağrıldı
    -f) opt_f=1;shift 1;; # opt_f değişkenine değer atandı
    -l) opt_l=$2;shift 2;; # -l parametresi değer almaktadır,
       -&gt; shift ile 2 kaydırıldıktan sonar
    --) shift;break;; # seçenekler bölümünün sonu
    -*) echo "hata: $1 seçeneği tanımlı değildir. yardım için -h";exit 1;;
    *)  break;;
esac
done

echo "opt_f nin değeri $opt_f"
echo "opt_l nin değeri $opt_l"
echo "ilk parametre $1"
echo "ikinci parametre $2"
</PRE>
    Bunu bir deneyin! Programı aşağıdaki gibi çalıştırabilirsiniz:
<PRE>
cmdparser -l merhaba -f -- -dosya1 dosya2
</PRE>
    sonuç
<PRE>
opt_f nin değeri 1
opt_l nin değeri merhaba
ilk parametre -dosya1
ikinci parametre dosya2
</PRE>
    Bu nasıl çalışmaktadır? Döngü içinde tüm parametreler tek tek case
    ifadesindekilere uyup uymadığı karşılaştırılmaktadır.
    Uyuan bir parametre bulunduğunda, değeri ilgili değişkene atanmakta ve
    bir kaydırılmaktadır. Unix'te, seçimler (- eksi işareti ile başlayanlar)
    önce gelmektedir. İki eksi (--) çizgisiyle seçimlerin bittiğini
    belirtebilirsiniz. Buna, eksi ile başlayan bir katarı grep ile ararken
    gereksiminiz olacaktır:
<PRE>
f.txt dosyasında -xx- arama:
grep -- -xx- f.txt
</PRE>
    Bizim parametre işlemcimiz, yukarıda da görüldüğü gibi, -- ile başlayan
    parametreleri de işleyebilmektedir.

    <A NAME="216lfindex5">&nbsp;</A>
<H2>Örnekler</H2>

    <B>Genel amaçlı program iskeleti</B><BR>
    <BR>
    Bir kabuk programı yazmak için gerekli olan tüm
    bileşenleri inceledik. Tüm iyi programlarda yardım
    bulunmalıdır ve seçenekleri işlemek, tek bir seçenek olsa bile,
    için genel amaçlı şeçenek işlemcimizden yararlanabilirsiniz.
    Dolayısıyla, başka programların yazımında temel alabileceğiniz
    <A href="../../common/src/article216/framework.sh.txt">framework.sh</A>,
    bir çerçeve programınızın olması, hiç de fena fikir değildir.
    Yeni bir program yazacağınız zaman, bundan bir kopya çıkartmanız yeterlidir:
<PRE>
cp framework.sh benimprogram
</PRE>
    ve bundan sonra "benimprogram" adlı programda gerekli değişiklikler
    yapılabilir. <BR>
    <BR>
    Şimdi şu iki programı inceleyelim: <BR>
    <BR>
    <B>İkili sayı tabanda verilen bir sayısı, onlu tabana çeviren program</B><BR>
    <BR>
     <A href="../../common/src/article216/b2d.txt">b2d</A>
     programı, ikili sayı tabanında verilen bir sayıyı (1101 gibi)
     karşılığı olan onlu tabana çevirmektedir. Bu program expr kullanarak basit
     matematiksel işlemlerin nasıl yapılabileceğiniz göstermektedir:
<PRE>
#!/bin/sh
# vim: set sw=4 ts=4 et:
yardim()
{
  cat &lt;&lt;YARDIM
b2h -- ikili sayı sisteminde verilen bir sayıyı, onlu sayı sisteme çevirir

KULANIM: b2h [-h] ikilisayi

SEÇENEKLER: -h yardım metin

ÖRNEK: b2h 111010
için sonuç 58 olur
YARDIM
  exit 0
}

hata()
{
    # hata mesajını görüntüle ve çık
    echo "$1"
    exit 1
}

sonkarakter()
{
    # $rval değişkeni içerisine, verilen katarın son karakterini yerleştirir
    if [ -z "$1" ]; then
        # boş katar
        rval=""
        return
    fi
    # wc, çıktının sonuna biraz boşluk koymaktadır,
    # sed'e gereksinim duymamızın nedeni budur:
    karaktersayisi=`echo -n "$1" | wc -c | sed 's/ //g' `
    # şimdi son karakteri elde et
    rval=`echo -n "$1" | cut -b $karaktersayisi`
}

kes()
{
    # verilen bir katarın son karakterini kesip, geriye kalanı
    # $rval içine yerleştirir
    if [ -z "$1" ]; then
        # boş katar
        rval=""
        return
    fi
    # wc, çıktının sonuna biraz boşluk koymaktadır, sed'e gereksinim
    # duymamızın nedeni budur:
    karaktersayisi=`echo -n "$1" | wc -c | sed 's/ //g' `
    if [ "$karaktersayisi" = "1" ]; then
        # katarda sadece bir karakter var
        rval=""
        return
    fi
    karaktersayisieksi1=`expr $karaktersayisi "-" 1`
    # son hariç hepsini al:
    rval=`echo -n "$1" | cut -b 0-${karaktersayisieksi1}`
}


while [ -n "$1" ]; do
case $1 in
    -h) yardim;shift 1;; # yardım fonksiyonu çağırıldı
    --) shift;break;; # seçeneklerin sonu
    -*) hata "hata: böyle bir seçenek yok. Yrdım için $1. -h ";;
    *)  break;;
esac
done

# Programın ana kısmı
toplam=0
agirlik=1
# bir parametre mutlaka verilmelidir:
[ -z "$1" ] &amp;&amp; yardim
ikilisayi="$1"
orjikilisayi="$1"

while [ -n "$ikilisayi" ]; do
    sonkarakter "$ikilisayi"
    if [ "$rval" = "1" ]; then
        toplam=`expr "$agirlik" "+" "$toplam"`
    fi
    # $ikilisayi'daki son karakteri çıkart
    kes "$ikilisayi"
    ikilisayi="$rval"
    agirlik=`expr "$agirlik" "*" 2`
done

echo "İkili sayı sistemindeki $orjikilisayi nın
      onlu sayı sistemindeki değeri $toplam dır"

</PRE>
    Kullanılan algoritma, sağ taraftan başlayarak, her basamaktaki sayının
    ağırlığını (1,2,4,8,16,..) kullanarak, eğer ilgili basamaktaki sayı 1 ise,
    toplam değişkenine eklemektedir.  Sözgelimi "10", 0 * 1 + 1 * 2 = 2 dir. <BR>
    Katarın her bir basmak sayısını elde etmek için sonkarakter
    fonksiyonunu kullanıyoruz. Bu fonksiyon, katardaki toplam karakter sayısını
    bulabilmek için wc -c komutundan yararlanmaktadır. Daha sonra da, son karakteri
    elde etmek için cut komutundan yararlanmaktadır. kes fonksiyonu da benzer bir mantıkla
    çalışmaktadır, ancak yaptığı iç katardaki sona karakterden kurtulup, ona kadar
    olanı elde etmektir.
    <BR>
    <BR>
     <B>Dosya çevirme programı</B><BR>
    Belkide siz, göndermiş olduğunuz tüm e-iletilerinizi bir
    dosyada saklayanlardansınızdır. Birkaç aydan sonra bu dosyanın
    boyutu oldukça büyümekte ve e-ileti programıyla dosyaya olan
    erişimi yavaşlatnmaktadır.
    <A href="../../common/src/article216/rotatefile.txt">rotatefile</A>
    programı size yardımcı olabilir. Program, eileti dizininizin adını, adı gideneileti
    olsun, gidenelileti.1, gidenelileti.2 vs. olarak değiştirmektedir.
<PRE>
#!/bin/sh
# vim: set sw=4 ts=4 et:
surum="0.1"
yardim()
{
    cat &lt;&lt;YARDIM
rotatefile -- dosya adını çevirir

KULLANIM: rotatefile [-h]  dosyaadi

SEÇENEKLER: -h yardim metin

ÖRNEK: rotatefile giden
Bu program giden.2 yi giden.3, giden.1 i giden.2, giden i  giden.1 olarak
değiştirerek boş bir giden dosyası yaratacaktır

En fazla 10'a kadar değiştirmektedir.

sürüm $surum
YARDIM
    exit 0
}

hata()
{
    echo "$1"
    exit 1
}
while [ -n "$1" ]; do
case $1 in
    -h) yardim;shift 1;;
    --) break;;
    -*) echo "hata: böyle bir seçenek yoktur $1. Yardım için -h";exit 1;;
    *)  break;;
esac
done

# girilen verileri denetleme:
if [ -z "$1" ] ; then
 error "HATA: parametre olarak dosya vermeniz gerekmektedir,
        yardım için -h kullanınız"
fi
dosyan="$1"
# .1 , .2 vs. dosyalrını adını değiştir:
for n in  9 8 7 6 5 4 3 2 1; do
    if [ -f "$dosyan.$n" ]; then
        p=`expr $n + 1`
        echo "mv $dosyan.$n $dosyan.$p"
        mv $dosyan.$n $dosyan.$p
    fi
done
# orijinal dosyayı:
if [ -f "$dosyan" ]; then
    echo "mv $dosyan $dosyan.1"
    mv $dosyan $dosyan.1
fi
echo touch $ya
touch $dosyan

</PRE>
    Bu nasıl çalışmaktadır? Kullanıcının parametre olarak dosya verdiğini
    denetledikten sonra, program, 9'dan 1'e doğru bir döngü içerisine
    girmektedir. Dolayısıyla, 9. dosya 10, 8. dosya 9 vs. olmaktadır.
    Döngü bittikten sonra, orijinal dosyayi 1 olarak adını değiştirdikten sonra
    orijinal dosya adında boş bir dosya yaratılmaktadır.

    <A NAME="216lfindex6">&nbsp;</A>
<H2>Hata ayıklama</H2>

    Hata ayıklamada kullanılan en basit yöntem echo komutunu kullanmaktır.
    Bu komutu hatanın olabileceğini düşündüğünüz yerde kullanabilirsiniz.
    Bu belkide hata bulmada, kabuk programları yazan kişilerin %80'ninin kullandığı
    yöntemdir. Kabuk programlarının avantajı derlemeye gereksinim duymamaları
    ve bu yüzden echo komutunu eklemek uzun sürmemektedir. <BR>
    <BR>
    Kabukta, gerçek hata ayıklama seçeneği de vardır. Eğer, "garipbetik" adlı
    programda hata varsa, hatayı:
<PRE>
sh -x garipbetik
</PRE>
    kullanarak bulabilirsiniz.<BR>
    Programı bu şekilde çalıştırdığınızda, çalıştırılan tüm
    komutları, değişkenlerin değerleri ve joker karakterler (*,? gibi)
    varsa, yerlerine karşılıklarını yerleştirerek görüntülemektedir.
    <BR>
    <BR>
    Ayrıca, kabukta, programı çalıştırmadan, yazım hatalarını
    denetleyen seçeneği de vardır. Bunun için:
<PRE>
sh -n sizin_programiniz
</PRE>
    Eğer, sonuçta hiç bir şey görüntülenmiyorsa, yazılım hatası yok demektir.
    <BR>
    <BR>
    Bundan sonra kabuk programları yazmaya başlmanız dileği ile. İyi eylenceler!
    <BR>


    <A NAME="216lfindex7">&nbsp;</A>
<H2>Kaynaklar</H2>


    <UL>
      <LI>Bash kabuğun man ve info sayfaları çok iyi yazılmış ve orada birçok
      faydalı kullanım bulabilirsiniz:
      <BR>
      man bash<BR>
      tkinfo bash<BR>
      (Ben standart info gezgininden nefret ediyorum, ancak <A href=
      "http://math-www.uni-paderborn.de/~axel/tkinfo/">tkinfo</A> veya
      konqueror (url için info:/bash/Top ) oldukça iyidir)</LI>

      <LI>LinuxFocus'un  <A href=
      "../November2000/article131.shtml">GNU dosya araçları</A> yazısı.</LI>

      <LI>LinuxFocus'un <A href=
      "../July1998/article53.html">Düzenli yapılar</A> yazısı.</LI>

      <LI>LinuxFocus'un  <A href=
      "../September1999/article103.html">AWK</A> yazısı.</LI>

      <LI>LinuxFocus'un <A href=
      "../November1998/article68.html">Temel UNIX komutları</A> yazısı</LI>

      <LI>Eğer, sisteminizde bash yüklü değil ise, veya
      son sürümünü elde etmek istiyorsanız, GNU'nun sanaldoku yöresinden
      (http://www.gnu.org) elde edebilirsiniz(Sisteminizde bash olup olmadığını
      anlamak için bash komutunu çalıştırınız. Eğer, herhabgi bir hatayla
      karşılaşmıyorsanız, o zaman bash kabuğu yüklü demektir.)</LI>
    </UL>
    <!-- vim: set sw=2 ts=2 et: -->
  




<!-- 2pdaIgnoreStart -->
<A NAME="talkback">&nbsp;</a>
<h2>Bu yazı için görüş bildiriminde bulunabilirsiniz</h2>
Her yazı kendi görüş bildirim sayfasına sahiptir. Bu sayfaya yorumlarınızı yazabilir ve diğer okuyucuların yorumlarına bakabilirsiniz.
<center>
<table border="0"  CELLSPACING="2" CELLPADDING="1">
 <tr BGCOLOR="#C2C2C2"><td align=center>
  <table border="3"  CELLSPACING="2" CELLPADDING="1">
   <tr BGCOLOR="#C2C2C2"><td align=center>
    <A href="http://cgi.linuxfocus.org/cgi-bin/lftalkback?anum=216&lang=en"><b>&nbsp;talkback page&nbsp;</b></a>
   </td></tr></table>
</td></tr></table>
</center>

<HR size="2" noshade>
<!-- ARTICLE FOOT -->
<CENTER><TABLE WIDTH="95%">
<TR><TD ALIGN=CENTER BGCOLOR="#9999AA">
<A HREF="../../common/lfteam.html">Görselyöre sayfalarının bakımı, LinuxFocus Editörleri tarafından yapılmaktadır</A>
<BR><FONT COLOR="#FFFFFF">&copy; Katja and Guido     Socher, <a href="../../common/copy.html">FDL</a> <BR><a href="http://www.linuxfocus.org">LinuxFocus.org</a></FONT>
<BR><a href="http://cgi.linuxfocus.org/cgi-bin/lfcomment?lang=tr&article=article216.shtml" target="_TOP">Burayı klikleyerek hataları rapor edebilir ya da yorumlarınızı LinuxFocus'a gönderebilirsiniz</A><BR></TD>
<TD BGCOLOR="#9999AA"><!-- TRANSLATION INFO -->
<font size=2>Çeviri bilgisi:</font><TABLE>
<tr><td><font size=2>en</font></td>
    <td><font size=2>-&gt;</font></td>
    <td><font size=2>--</font></td>
    <td><font size=2><a href="mailto:katja&#64;linuxfocusorg, guido@linuxfocus.org"><FONT COLOR="#FFFFFF">Katja and Guido     Socher</FONT></a></font></td>
</tr>
<tr><td><font size=2>en</font></td>
    <td><font size=2>-&gt;</font></td>
    <td><font size=2>tr</font></td>
    <td><font size=2><a href="mailto:ceyhun.elmas&#64;linuxfocus.org, erdal@linuxfocus.org"><FONT COLOR="#FFFFFF">Ceyhun ELMAS ve Erdal MUTLU</FONT></a></font></td>
</tr>
</TABLE></TD>
</TR></TABLE></CENTER>
<p><font size=1>2001-09-17, generated by lfparser version 2.17</font></p>
<!-- 2pdaIgnoreStop -->
</BODY>
</HTML>