İşletim Sistemleri İşletim Sistemleri Dr. Binnur Kurt binnur.kurt@gmail.com Omega Eğitim ve Danışmanlık http://www.omegaegitim.com Bölüm 2 Kabuk 1|Sayfa İşletim Sistemleri İÇİNDEKİLER 1. İşletim Sistemleri 2. Kabuk 3. Prosesler 4. İplikler 5. Prosesler Arası İletişim 6. İş Sıralama 7. Ölümcül Kilitlenme 8. Çok İplikli Programlama 9. Bellek Yönetimi 10. Dosya Sistemi 11. Socket Haberleşme Bölüm 2 Kabuk 2|Sayfa İşletim Sistemleri BÖLÜM 2 Kabuk Bölümün Amacı Bölüm sonunda aşağıdaki konular öğrenilmiş olacaktır: ► Kabuğun özellikleri ve işletim sistemindeki görevleri ► Kabuk komut formatı ► Kabuk programlama o Değişkenler o Aritmetik İşlemler o Koşullar ve Döngüler Bölüm 2 Kabuk 3|Sayfa İşletim Sistemleri 2.1 Kabuk nedir? İşletim sistemlerinde, çekirdek sistem kaynaklarını yönetmekten sorumludur. Bunun için çok sayıda servisten oluşur. Bu servisler genel olarak prosesler arasında işlemci ve bellek gibi kaynaklara erişimini düzenler. Servislere sistem çağrıları ile ulaşılır. İşletim sistemi ile kullanıcı programları arasında tanımlanmış bir arayüz vardır. Bu arayüz bir dizi yordamdan oluşur. Bu yordamların neler olduğu, aldıkları parametreler ve parametre tipleri IEEE POSIX standardı tarafından tanımlanmıştır. Bu yordamlara ulaşmak için trap işletimci komutundan yararlanılır. trap kesmesi ile birlikte kontrol ilgili yordama geçer ve kod çekirdek seviyesinde koşmaya başlar. Ancak sistem çağrıları alt düzey çağrılar olduğu için, sistem yönetimi ile ilgili işler için sistem çağrılarını kullanmak zordur. Bunun için sistem komutlarını kullanıyoruz. Örneğin dosya kopyalamak için cp komutu kullanılır. Kabuk kullanıcı için bir komut satırı sağlar ve buradan kullanıcının girdiği komutları çalıştırır ve sonucu listeler. Kabuğun görevleri aşağıdaki gibi sıralanabilir: a. Çekirdek ile kullanıcı arasında bir arayüz tanımlar. b. Komut satırı yorumlayıcısıdır. Kullanıcıdan aldığı komutları çekirdeğin anlayacağı sistem çağrılarına dönüştürür. c. Programlama ortamı sağlar. Böylelikle karmaşık komutlar ya da periyodik olarak çalıştırılacak işler bir betik haline getirilebilir. Bu betikler ilgili kabuk tarafından çalıştırılır. 2.2 Kabuk Türleri Tarihsel olarak Unix işletim sistemi geliştirilirken çok sayıda kabuk yazıldığını görüyoruz. Bunlar arasında çok sık karşılaştığımız kabukların listesini aşağıda veriyorum: Bourne Shell sh Korn Shell ksh C Shell csh TC Shell tcsh B(ourne)A(gain) Shell bash Desktop Korn Shell dtksh Job Control Shell jsh Restricted Shell rsh Z Shell zsh Bu kabuklar arasında hız, güvenlik seviyesi, programlama yetenekleri gibi farklılıklar bulunur. Bu kabuklardan sıkça kullanılan birkaç tanesine bir göz atalım. 2.2.1 Bourne Shell (sh) AT&T Bell laboratuvarında Steve R. Bourne tarafından yazılmıştır. Kabuk betiklerinde en çok tercih edilen kabuktur. Bourne kabuğu, hız ve taşınabilirliği ile öne çıkmaktadır. Solaris işletim sisteminde varsayılan kabuk sh’dır. Ancak bazı önemli eksikleri bulunmaktadır: eski komutları hatırlamaz, aritmetik ve mantıksal işleçler Bölüm 2 Kabuk 4|Sayfa İşletim Sistemleri bulunmaz. root kullanıcısı için varsayılan imleç # ve diğer kullanıcılar için ise imleç $ sembolleridir. Solaris işletim sisteminde açılış betikleri Bourne kabuğu tarafından çalıştırılır. 2.2.2 C Shell (csh) California Üniversitesinde, Bill Joy tarafından yazılmıştır. Önceki komutları hatırlaması, aritmetik ve C benzeri ifadeler yazılabilmesi ve takma isim tanımlanabilmesi en önemli özellikleridir. Ancak Bourne kabuğundan daha yavaştır. root kullanıcısı için varsayılan imleç # ve diğer kullanıcılar için ise imleç % sembolleridir. 2.2.3 Korn Shell (ksh) AT&T Bell laboratuvarında David Korn tarafından yazılmıştır. Bourne kabuğunu kapsar. Bu nedenle Bourne kabuğu için yazılan betikler Korn kabuğunda da çalışabilir. C kabuğu ile benzer özelliklere sahiptir. Önceki komutları hatırlar, aritmetik ve mantıksal işlemleri destekler, dizi ve fonksiyon tanımlanabilir. C kabuğundan daha hızlıdır. root kullanıcısı için varsayılan imleç # ve diğer kullanıcılar için ise imleç $ sembolleridir. GNU/Linux işletim sisteminde varsayılan kabuk BASH’dir. 2.3 Komut Formatı Kabuk kullanıcıdan aldığı komutları çalıştırır. Bu komutların belirli bir formatı vardır. Komutlar – ile verilen seçenek ile parametre değerlerini alırlar. Komutların düzgün kullanımı için seçeneklerin ve parametrelerin neler olduğunun bilinmesi gerekir. Bunun için öncelikli olarak man komutuna başvurulabilir: [student@server1 ~]$ man cal Bölüm 2 Kabuk 5|Sayfa İşletim Sistemleri Bir komutu eğer izin veriyorsa birden fazla seçenekle yada seçeneksiz olarak çalıştırabiliriz: [student@server1 ~]$ uname Linux [student@server1 ~]$ uname -a Linux server1.example.com 3.8.13-16.2.1.el6uek.x86_64 #1 SMP Thu Nov 7 17:01:44 PST 2013 x86_64 x86_64 x86_64 GNU/Linux [student@server1 ~]$ uname -i x86_64 [student@server1 ~]$ uname -r 3.8.13-16.2.1.el6uek.x86_64 [student@server1 ~]$ uname -s Linux [student@server1 ~]$ uname -r -s Linux 3.8.13-16.2.1.el6uek.x86_64 [student@server1 ~]$ uname -s -r Linux 3.8.13-16.2.1.el6uek.x86_64 [student@server1 ~]$ uname -rs Linux 3.8.13-16.2.1.el6uek.x86_64 [student@server1 ~]$ uname -sr Linux 3.8.13-16.2.1.el6uek.x86_64 [student@server1 ~]$ uname -rs -i Linux 3.8.13-16.2.1.el6uek.x86_64 x86_64 [student@server1 ~]$ uname -rsi Linux 3.8.13-16.2.1.el6uek.x86_64 x86_64 [student@server1 ~]$ uname -r -s -i Linux 3.8.13-16.2.1.el6uek.x86_64 x86_64 Yukarıda uname komutunu herhangi bir seçenek vermeden çalıştırdık. Birden fazla seçenek vererek çalıştırdık. Birden fazla seçenek alması durumunda bu seçenekleri toplu olarak verebileceğimiz gibi ayrı ayrı da verebiliriz: -sir ile -s –i -r aynı anlama gelir. Benzer şekilde –si -r ile -s –i -r aynı anlama gelir. Bazen komutlar parametre alabilirler. Cal komutu ekrana takvimi döker. Eğer bir parametre verilmemiş ise içinde bulunulan yılın ve ayın takvimini ekrana döker. İstenirse ay ve yıl parametreleri verilebilir: [student@server1 ~]$ cal September 2014 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 [student@server1 ~]$ cal 7 1973 July 1973 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Bölüm 2 Kabuk 6|Sayfa İşletim Sistemleri 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 İstenirse sadece yıl parametre olarak verilerek o yılın takvimi ekrana dökülebilir: [student@server1 ~]$ cal 1973 1973 Su Mo 1 7 8 14 15 21 22 28 29 January Tu We Th 2 3 4 9 10 11 16 17 18 23 24 25 30 31 April Tu We Th 3 4 5 10 11 12 17 18 19 24 25 26 Fr 5 12 19 26 Sa 6 13 20 27 Fr 6 13 20 27 Sa 7 14 21 28 Su 1 8 15 22 29 Mo 2 9 16 23 30 Su 1 8 15 22 29 Mo 2 9 16 23 30 July Tu We Th 3 4 5 10 11 12 17 18 19 24 25 26 31 Fr 6 13 20 27 Sa 7 14 21 28 Su Mo 1 7 8 14 15 21 22 28 29 October Tu We Th 2 3 4 9 10 11 16 17 18 23 24 25 30 31 Fr 5 12 19 26 Sa 6 13 20 27 February Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Su Mo Tu 1 6 7 8 13 14 15 20 21 22 27 28 29 May We Th 2 3 9 10 16 17 23 24 30 31 Fr 4 11 18 25 Sa 5 12 19 26 August Su Mo Tu We Th 1 2 5 6 7 8 9 12 13 14 15 16 19 20 21 22 23 26 27 28 29 30 Fr 3 10 17 24 31 Sa 4 11 18 25 November Su Mo Tu We Th 1 4 5 6 7 8 11 12 13 14 15 18 19 20 21 22 25 26 27 28 29 Fr 2 9 16 23 30 Sa 3 10 17 24 March Su Mo Tu We Th 1 4 5 6 7 8 11 12 13 14 15 18 19 20 21 22 25 26 27 28 29 Fr 2 9 16 23 30 Sa 3 10 17 24 31 June Su Mo Tu We Th Fr 1 3 4 5 6 7 8 10 11 12 13 14 15 17 18 19 20 21 22 24 25 26 27 28 29 Sa 2 9 16 23 30 September Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 December Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Yukarıdaki örneklerden de anlaşılacağı gibi komutların kaç parametre alabildikleri ve parametrelerin sırasının bir önemi bulunmaktadır. Bu sıralamanın ne olduğunu öğrenmek için man komutu ile kullanım kılavuzunu (=Manual Page) okumak gerekir. Bazen komutlar hem seçenek hem de parametre verilerek çalıştırılır: [student@server1 /]$ ls bin boot cgroup dev etc home lib lib64 lost+found media misc mnt net opt oradata proc root sbin selinux srv sys tmp usr var [student@server1 /]$ ls -l total 106 dr-xr-xr-x. 2 root root dr-xr-xr-x. 5 root root drwxr-xr-x. 10 root root drwxr-xr-x. 20 root root drwxr-xr-x. 125 root root drwxr-xr-x. 5 root root drwxr-xr-x. 11 root root dr-xr-xr-x. 10 root root drwx------. 2 root root drwxr-xr-x. 3 root root Bölüm 2 Kabuk 4096 1024 4096 4260 12288 4096 4096 12288 16384 4096 Apr Apr Apr Sep Sep Apr Nov Apr Apr Sep 30 29 29 22 22 30 8 30 29 22 03:49 11:31 11:38 00:34 00:38 02:22 2013 03:49 11:09 00:35 bin boot cgroup dev etc home lib lib64 lost+found media 7|Sayfa İşletim Sistemleri drwxr-xr-x. 2 root drwxr-xr-x. 4 root drwxr-xr-x. 2 root drwxr-xr-x. 15 root drwxr-xr-x. 3 oracle dr-xr-xr-x. 180 root dr-xr-x---. 38 root dr-xr-xr-x. 2 root drwxr-xr-x. 7 root drwxr-xr-x. 2 root dr-xr-xr-x. 13 root drwxrwxrwt. 20 root drwxr-xr-x. 15 root drwxr-xr-x. 22 root root 0 Sep 16 18:44 misc root 4096 Apr 30 06:02 mnt root 0 Sep 16 18:44 net root 4096 May 12 01:26 opt oracle 4096 Apr 30 03:37 oradata root 0 Sep 16 18:44 proc root 4096 Sep 22 01:34 root root 12288 May 6 09:35 sbin root 0 Sep 16 18:44 selinux root 4096 Nov 1 2011 srv root 0 Sep 16 18:44 sys root 4096 Sep 22 01:50 tmp root 4096 May 11 20:58 usr root 4096 Apr 29 11:28 var [student@server1 /]$ ls -l /var total 80 drwxr-xr-x. 2 root root 4096 Apr drwxr-xr-x. 17 root root 4096 Apr drwxr-xr-x. 2 root root 4096 Nov drwxr-xr-x. 2 root root 4096 Oct drwxr-xr-x. 3 root root 4096 Apr drwxr-xr-x. 3 root root 4096 Apr drwxr-xr-x. 2 root root 4096 Nov drwxrwx--T. 2 root gdm 4096 Nov drwxr-xr-x. 46 root root 4096 Apr drwxr-xr-x. 2 root root 4096 Nov drwxrwxr-x. 6 root lock 4096 Sep drwxr-xr-x. 14 root root 4096 Sep lrwxrwxrwx. 1 root root 10 Apr drwxr-xr-x. 2 root root 4096 Nov drwxr-xr-x. 2 root root 4096 Nov drwxr-xr-x. 2 root root 4096 Nov drwxr-xr-x. 32 root root 4096 Sep drwxr-xr-x. 14 root root 4096 Apr drwxrwxrwt. 3 root root 4096 Sep drwxr-xr-x. 6 root root 4096 Apr drwxr-xr-x. 3 root root 4096 Apr 29 29 18 11 29 29 1 22 30 1 21 21 29 1 1 1 21 29 11 29 29 11:28 11:38 2013 2013 11:28 11:25 2011 2013 02:17 2011 21:11 21:11 11:10 2011 2011 2011 20:38 11:22 10:52 11:21 11:21 account cache crash cvs db empty games gdm lib local lock log mail -> spool/mail nis opt preserve run spool tmp www yp Bazen uzun soluklu bir komutu çalıştırdığımızda, tamamlanmasını beklemeden sonlandırmak isteriz. Bu durumda Ctrl+C tuşlarına basmamız yeterli olur: [student@server1 /]$ sleep 10 (10 saniye sonra) [student@server1 /]$ sleep 10 ^C Kabuk her seferinde tek bir komut çalıştırır. Bazen birden fazla komutu tek bir seferde verip, çalıştırılmasını isteriz. Bu durumda birden fazla komutu, komutlar arasına ; sembolü koyarak giriyoruz: [student@server1 /]$ cal 7 1973 ; date ; uname -rs July 1973 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Bölüm 2 Kabuk 8|Sayfa İşletim Sistemleri 22 23 24 25 26 27 28 29 30 31 Mon Sep 22 01:58:19 EEST 2014 Linux 3.8.13-16.2.1.el6uek.x86_64 2.4 Alt Kabuk Her kullanıcı için bir varsayılan kabuk vardır. Bunu echo $SHELL komutu ile öğrenebiliriz: [student@server1 ~]$ echo $SHELL /bin/bash Bu örnekte varsayılan kabuğun Bash olduğunu anlıyoruz. Şu an kullanmakta olduğumuz kabuğu anlamak için ps komutunu çalıştırmamız yeterli olur: [student@server1 ~]$ ps PID TTY TIME CMD 3819 pts/0 00:00:00 bash 3843 pts/0 00:00:00 ps ps komutu açtığımız terminalde çalışan uygulamaların listesini verir. Tüm çalışan uygulamaların yani proseslerin listesini almak için ps -fe komutunu kullanıyoruz: Bu örnekte Bash kabuğu ile konuştuğumuzu anlıyoruz. (Şekil-2.1) Bölüm 2 Kabuk 9|Sayfa İşletim Sistemleri Şekil-2.1 Bash kabuğunun çalıştığı terminal penceresi Bir kabuktan diğerine geçiş yapmak mümkündür. Bunun için basitçe geçiş yapmak istediğimiz kabuğun komutunu çalıştırmak yeterli olur. Geçiş yaptığımız kabuğa alt kabuk adını veriyoruz. Şimdi önce Korn kabuğuna ardından C kabuğuna geçiş yapalım: [student@server1 ~]$ ksh $ ps PID TTY TIME CMD 3819 pts/0 00:00:00 bash 5746 pts/0 00:00:00 ksh 5747 pts/0 00:00:00 ps $ csh [student@server1 ~]$ ps PID TTY TIME CMD 3819 pts/0 00:00:00 bash 5746 pts/0 00:00:00 ksh 5749 pts/0 00:00:00 csh 5757 pts/0 00:00:00 ps Oluşan yapıyı Şekil-2.2’den izleyebilirsiniz. Tekrar üst kabuğa geri dönmek için ise exit komutu çalıştırılır: [student@server1 ~]$ exit $ ps PID TTY TIME CMD 3819 pts/0 00:00:00 bash 5746 pts/0 00:00:00 ksh 5801 pts/0 00:00:00 ps $ exit [student@server1 ~]$ ps PID TTY TIME CMD 3819 pts/0 00:00:00 bash 5802 pts/0 00:00:00 ps Bölüm 2 Kabuk 10 | S a y f a İşletim Sistemleri bash exit ksh ksh exit csh csh Şekil-2.2 Alt kabuklar arası geçişler 2.5 Kabuk Değişkenleri Alt kabuk kavramı özellikle çevre değişkenleri ile çalışırken önemlidir. İki tür çevre değişkeni bulunur: Yerel ve Global. Çevre değişkeni tanımlamak son derece kolaydır: [student@server1 ~]$ VAR1=deneme [student@server1 ~]$ echo $VAR1 deneme Burada VAR1 değişkeni yerel bir değişkendir. Değişkenlerin değerlerini echo komutu ile öğrenebiliriz. echo komutu ile değişkeni adreslerken değişkeninin adının önüne $ sembolü koyuyoruz. Yerel değişken olduğu için bir alt kabukta çalışmaya başladığımızda değerine erişemiyoruz: [student@server1 ~]$ ksh $ echo $VAR1 $ exit [student@server1 ~]$ echo $VAR1 deneme Değişkeni global yapmak için ise export komutunu kullanıyoruz: [student@server1 ~]$ export VAR1=deneme [student@server1 ~]$ echo $VAR1 deneme [student@server1 ~]$ ksh $ echo $VAR1 deneme $ exit [student@server1 ~]$ echo $VAR1 deneme Şimdi VAR1 değişkeni global bir değişkene dönüştüğünden Korn kabuğundan değerine ulaşabildik. Bölüm 2 Kabuk 11 | S a y f a İşletim Sistemleri Yerel ve global değişkenler arasındaki farkı gösteren başka bir örneği aşağıda bulabilirsiniz. Bu örnek x değişkeninin yerel değişken olarak, name değişkeninin ise export komutu ile global değişken olarak tanımlandığına dikkat ediniz: [student@server1 ~]$ x=108 [student@server1 ~]$ name="John Locke" [student@server1 ~]$ echo $name $x John Locke 108 [student@server1 ~]$ export name [student@server1 ~]$ ksh $ print $x $ print $name John Locke $ exit [student@server1 ~]$ Korn alt kabuğunda name değişkenine erişebilirken x değişkenine erişemedik. export komutunun kullanımına ilişkin diğer detayları aşağıdaki örneği inceleyerek öğreneceğiz: [student@server1 ~]$ var=value [student@server1 ~]$ export var [student@server1 ~]$ var=value ; export var [student@server1 ~]$ export var=value [student@server1 ~]$ export x=108 y=549 z=4629 [student@server1 ~]$ echo $x 108 [student@server1 ~]$ echo $y 549 [student@server1 ~]$ echo $z 4629 ; ile birden fazla komutu tek bir seferde kabuğa geçirmemiz mümkündür: var=value ; export var Burada yapılan işlem export var=value ile yapılan işlemle aynıdır. export komutu ile bir kerede birden fazla değişken tanımlanabilir. Kabuk değişkenlerine erişmek için daha yetenekli olan ${} gösterimi de kullanılmaktadır: [student@server1 ~]$ counter=1 [student@server1 ~]$ echo $counter 1 [student@server1 ~]$ echo ${counter} 1 ${} gösteriminin başka yetenekleri de vardır. Bu yetenekleri aşağıdaki örneklerde görmeye çalışalım: [student@server1 ~]$ var=x [student@server1 ~]$ echo ${var:-y} x [student@server1 ~]$ var= [student@server1 ~]$ echo ${var:-y} y [student@server1 ~]$ unset var [student@server1 ~]$ echo ${var:=y} Bölüm 2 Kabuk 12 | S a y f a İşletim Sistemleri y [student@server1 ~]$ echo ${var:=z} y [student@server1 ~]$ echo $var y Burada ${var:-y} ile var değişkenin değeri yoksa y değerini kullanması isteniyor. Burada değişkenin değerinin değişmediğine dikkat edin. Eğer değişkeninin değerinin değişmesini istiyorsanız ${var:=y} gösterimini kullanmalısınız. Değişkenin değeri üzerinde + sembolü kullanılarak bitiştirme işlemi yapılabilir: [student@server1 ~]$ for f in 4 8 15 16 23 42 > do > list=${list:+$list,}$f > done [student@server1 ~]$ echo $list 4,8,15,16,23,42 Değişken çift tırnak içinde kullanıldığında değişkeninin içeriğindeki görünmeyen karakterler ekrana basılır: [student@server1 ~]$ list="a b c d e f" [student@server1 ~]$ echo $list a b c d e f [student@server1 ~]$ echo "$list" a b c d e f 2.6 Kabuk Betikleri Çok sık çalıştırdığımız kalabalık seçenekleri olan ya da karmaşık komutları betik dosyası oluşturarak komut satırından kolayca erişilebilir hale getirebiliriz. Bunun dışında periyodik olarak çalıştırılacak işlerimiz varsa, yine bu işleri, betik dosyası oluşturup örneğin crontab servisini kullanarak otomatik olarak çalıştırabiliriz. Benzer şekilde basit karmaşıklıktaki sistem seviyesindeki problemler için betik yazmayı tercih ederiz. Daha karmaşık problemler için Perl, Python gibi daha üst düzey dilleri kullanmayı tercih ederiz. Betik dosyaları oluşturulurken belirli bir kabuk tercih edilir ve çalıştırmasını istediğimiz kabuğu ilk satırda belirtiriz: #!/bin/sh set -- * files=$# set -- */ dirs=$# echo “Dosya sayisi ($PWD): $files” echo “Katalog sayisi ($PWD): $dirs” Yukarıdaki betiği first.sh dosyasında oluşturmuş olalım. Bu betiği çalıştırabilmek için çalışma yetkisi vermemiz gerekir: [student@server1 ~]$ chmod +x first.sh Artık çalıştırabiliriz: [student@server1 ~]$ ./first.sh Dosya sayisi (/home/student): 19 Bölüm 2 Kabuk 13 | S a y f a İşletim Sistemleri Katalog sayisi(/home/student): 16 Betiği çalıştırmanın başka yolları da bulunmaktadır: a. . komutu ile çalıştırmak [student@server1 ~]$ . ./first.sh Dosya sayisi (/home/student): 19 Katalog sayisi(/home/student): 16 b. source komutu ile çalıştırmak [student@server1 ~]$ source ./first.sh Dosya sayisi (/home/student): 19 Katalog sayisi(/home/student): 16 c. betik dosyasının adını vererek çalıştırmak [student@server1 ~]$ ./first.sh Dosya sayisi (/home/student): 19 Katalog sayisi(/home/student): 16 d. Kabuk komutu ile çalıştırmak [student@server1 ~]$ sh ./first.sh Dosya sayisi (/home/student): 19 Katalog sayisi(/home/student): 16 a, b ve d’de verilen yöntemlerde betik dosyasının çalışma izninin olmasına bakılmaz. a ve b yöntemlerinde betik mevcut kabuk tarafından çalıştırılır, ayrı bir proses yaratılmaz. c ve d’de ise alt kabuk yaratılır ve betik bu alt kabuk tarafından çalıştırılır. Bu yüzden betik içinde tanımlana değişkenler export komutu ile tanımlanmış olsa bile, betik çalıştırılıp, kabuğa dönüldüğünde değişkene erişilemez: [student@server1 ~]$ echo $VAR1 [student@server1 [student@server1 deneme [student@server1 [student@server1 ~]$ . ./second.sh ~]$ echo $VAR1 [student@server1 [student@server1 deneme [student@server1 [student@server1 ~]$ source ./second.sh ~]$ echo $VAR1 ~]$ unset VAR1 ~]$ echo $VAR1 ~]$ unset VAR1 ~]$ echo $VAR1 [student@server1 ~]$ ./second.sh [student@server1 ~]$ echo $VAR1 [student@server1 ~]$ sh ./second.sh [student@server1 ~]$ echo $VAR1 [student@server1 ~]$ second.sh betiğinin içeriği aşağıdaki gibidir: #!/bin/sh export VAR1=deneme Bölüm 2 Kabuk 14 | S a y f a İşletim Sistemleri 2.7 Özel Kabuk Değişkenleri Kabukla çalışırken kullanabileceğimiz özel değişkenler vardır. Şimdi bu değişkenlere bir göz atalım: $$ Çalışan prosesin proses kimlik numarasını verir [student@server1 ~]$ cat third.sh #!/bin/sh echo $$ [student@server1 ~]$ ps PID TTY TIME CMD 3819 pts/0 00:00:00 bash 9876 pts/0 00:00:00 ps [student@server1 ~]$ echo $$ 3819 [student@server1 ~]$ ./third.sh 9879 [student@server1 ~]$ . ./third.sh 3819 [student@server1 ~]$ source ./third.sh 3819 [student@server1 ~]$ sh ./third.sh 9888 $? Son çalıştırılan prosesin exit değerini verir. Eğer sıfırsa işlem başarılı olmuştur. Sıfır dışındaki tüm değerler bir problemi işaret eder. Betiklerde hatalı durumları yakalamak için kullanılır. [student@server1 ~]$ ls /nodir ls: cannot access /nodir: No such file or directory [student@server1 ~]$ echo $? 2 [student@server1 ~]$ ls / bin dev lib media net proc selinux tmp boot etc lib64 misc opt root srv usr cgroup home lost+found mnt oradata sbin sys var [student@server1 ~]$ echo $? 0 [student@server1 ~]$ true ; echo $? 0 [student@server1 ~]$ false ; echo $? 1 $! Arka planda çalıştırılan prosesin kimlik numarasını öğrenmek için kullanılır. Aşağıdaki betik arka planda bir hesap makinası açar ve 10 saniye sonra bu hesap makinasını kapatır: Bölüm 2 Kabuk 15 | S a y f a İşletim Sistemleri #!/bin/sh gcalctool & while true ; do pid=$! sleep 10 kill -9 $pid break done & # Değişkenin içeriğinin karakter uzunluğunu verir. [student@server1 ~]$ export var="Hello Mars" [student@server1 ~]$ echo ${#var} 10 % Değişkenin içeriğinden sağdan ilk eşleşmeyi siler. %% Değişkenin içeriğinden sağdan ilk eşleşmeyi siler. # Değişkenin içeriğinden soldan ilk eşleşmeyi siler. ## Değişkenin içeriğinden soldan ilk eşleşmeyi siler. [student@server1 ~]$ var=/usr/local/bin/example [student@server1 ~]$ echo ${var%/*} /usr/local/bin [student@server1 ~]$ var=usr/local/bin/example [student@server1 ~]$ echo ${var%%/*} usr [student@server1 ~]$ var=usr/local/bin/example [student@server1 ~]$ echo ${var#*/} local/bin/example [student@server1 ~]$ var=usr/local/bin/example [student@server1 ~]$ echo ${var##*/} Example [student@server1 ~]$ export var=abcdef [student@server1 ~]$ echo ${var%${var#?}} a [student@server1 ~]$ echo ${var#${var%?}} f ${var//PATTERN/STRING} var değişkenindeki tüm PATTERN’leri STRING ile değiştirir. [student@server1 ~]$ echo -e "${var}\n${var//?/~}" Bölüm 2 - Kabuk ~~~~~~~~~~~~~~~ ${var:OFFSET:LENGTH} var değişkeninde OFFSET’ten itibaren LENGTH adet karakteri getirir [student@server1 ~]$ export var=abcdefgh [student@server1 ~]$ echo ${var:3:2} de Bölüm 2 Kabuk 16 | S a y f a İşletim Sistemleri [student@server1 ~]$ echo ${var:3} defgh 2.8 Aritmetik İşlemler Korn kabuğu ile çalışırken değişkenler üzerinde aritmetiksel ve mantıksal işlemler yapabiliriz. Aritmetik işlemler için toplama, çıkarma, çarpma, bölme ve bölümden kalan operatörlerini kullanabiliriz. Bu operatörlerin listesini Tablo-2.1’de bulabilirsiniz: Operatör İşlem Örnek Sonuç + Toplama ((x = 24 + 25)) 49 - Çıkarma ((x = 100 - 25)) 75 * Çarpma ((x = 4 * 5)) 20 / Bölme ((x = 10 / 3)) 3 % Bölümden Kalan ((x = 10 % 3)) 1 Tablo-2.1 Aritmetik İşlemler Korn kabuğunda tüm aritmetik işlemler tamsayı aritmetiği olarak gerçekleştirilir. Kayan noktalı sayılar için bir çözüm bulunmaz. Kayan noktalı sayılar ile işlem yapmak için bc komutunu kullanıyoruz. bc komutu bilimsel hesaplamalar da olmak üzere her türlü karmaşıklıktaki hesaplamalar için istenilen hassasiyette hesaplama yapılmasına izin verir: [student@server1 ~]$ echo "scale=8; a(1)*4" | bc -l 3.14159264 [student@server1 ~]$ echo "scale=16; a(1)*4" | bc -l 3.1415926535897932 [student@server1 ~]$ echo "scale=64; a(1)*4" | bc -l 3.1415926535897932384626433832795028841971693993751058209 749445920 [student@server1 ~]$ echo "scale=256; a(1)*4" | bc -l 3.1415926535897932384626433832795028841971693993751058209 74944592307\ 816406286208998628034825342117067982148086513282306647093 84460955058\ 223172535940812848111745028410270193852110555964462294895 49303819644\ 288109756659334461284756482337867831652712019091456484 Bölüm 2 Kabuk 17 | S a y f a İşletim Sistemleri Yukarıdaki örnekte PI sayısını istenilen basamak değerine kadar hesaplanabildiğini görüyoruz. Burada a(1), arctan trigonometrik fonksiyonunu göstermektedir. arctan(1) PI/4’dür. 2.9 Koşullu İfadeler Sonlanan her prosesin bir çıkış değeri bulunur. Bu değere göre prosesin başarılı olarak sonlanıp sonlanmadığı anlaşılabilir. 0 değeri işlemin başarıyla gerçekleştiğini gösterir. Sıfırdan her farklı değer işlemin başarısız olduğu anlamına gelir: [student@server1 /]$ if grep root /etc/passwd > then > echo "root bulundu." > fi root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin root bulundu. ya da [student@server1 /]$ if grep root /etc/passwd > /dev/null > then > echo "root bulundu." > fi root bulundu. Bir betiği belirli bir sayıda parametre ile çalıştırmak gerekiyorsa, bunun testi aşağıdaki gibi yapılabilir: if (( $# != 2 )) then print "KULLANIM: $0 arg1 arg2 " exit fi 2.10 Döngüler Döngü oluşturmak için birkaç yöntem bulunmaktadır. Bunlardan ilki for yapısını kullanmaktır: [student@server1 /]$ for meyve in elma portakal muz kavun karpuz > do > echo "Meyve: $meyve" > done Meyve: elma Meyve: portakal Meyve: muz Meyve: kavun Meyve: karpuz İkinci yöntem while yapısını kullanmaktır. while döngüsünde döngü koşulu doğru olana kadar döngü bloğu tekrar tekrar çalıştırılır. Aşağıdaki örnekte sayısal loto için 149 arasında bir birinden farklı altı sayı rastgele olarak belirlenmektedir: Bölüm 2 Kabuk 18 | S a y f a İşletim Sistemleri #!/bin/ksh (( r = RANDOM % 49 + 1 )) list="$r\n" for i in 2 3 4 5 6 ; do while true ; do (( r = RANDOM % 49 + 1 )) echo "$list" | grep "^$r$" > /dev/null if (( $? != 0 )) ; then break fi done list="$list\n$r" done list=$(echo "$list" | sort -n) echo $list Üçüncü yöntem until yapısını kullanmaktır. until döngüsünde while döngüsünü tersine, test koşulu yanlış olduğu sürece döngü döner: #!/bin/ksh num=1 until (( num == 6 )) do echo "The value of num is: $num" (( num = num + 1 )) done print "Done." Bölüm 2 Kabuk 19 | S a y f a
© Copyright 2024 Paperzz