Kabuk

İşletim Sistemleri
İşletim Sistemleri
Dr. Binnur Kurt
[email protected]
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