Kabuk

Transkript

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 Sistemi
2. Kabuk
3. Prosesler
4. İplikler
5. İplikler Arası Eş Zamanlama
6. Prosesler Arası İletişim
7. İş Sıralama
8. Prosesler Arası Eş zamanlama
9. Bellek Yönetimi
10. Dosya Sistemi
11. Soket 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
o Fonksiyonlar
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:
[[email protected] ~]$ man cal
Bölüm 2
Kabuk
5|Sayfa
İşletim Sistemleri
Bir komutu eğer izin veriyorsa birden fazla seçenekle ya da seçeneksiz olarak
çalıştırabiliriz:
[[email protected] ~]$ uname
Linux
[[email protected] ~]$ 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
[[email protected] ~]$ uname -i
x86_64
[[email protected] ~]$ uname -r
3.8.13-16.2.1.el6uek.x86_64
[[email protected] ~]$ uname -s
Linux
[[email protected] ~]$ uname -r -s
Linux 3.8.13-16.2.1.el6uek.x86_64
[[email protected] ~]$ uname -s -r
Linux 3.8.13-16.2.1.el6uek.x86_64
[[email protected] ~]$ uname -rs
Linux 3.8.13-16.2.1.el6uek.x86_64
[[email protected] ~]$ uname -sr
Linux 3.8.13-16.2.1.el6uek.x86_64
[[email protected] ~]$ uname -rs -i
Linux 3.8.13-16.2.1.el6uek.x86_64 x86_64
[[email protected] ~]$ uname -rsi
Linux 3.8.13-16.2.1.el6uek.x86_64 x86_64
[[email protected] ~]$ 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:
[[email protected] ~]$ 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
[[email protected] ~]$ 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:
[[email protected] ~]$ 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:
[[email protected] /]$ 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
[[email protected] /]$ 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
[[email protected] /]$ 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:
[[email protected] /]$ sleep 10
(10 saniye sonra)
[[email protected] /]$ 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:
[[email protected] /]$ 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:
[[email protected] ~]$ 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:
[[email protected] ~]$ 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:
[[email protected] ~]$ 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
[[email protected] ~]$ 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:
[[email protected] ~]$ 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
[[email protected] ~]$ 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:
[[email protected] ~]$ VAR1=deneme
[[email protected] ~]$ 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:
[[email protected] ~]$ ksh
$ echo $VAR1
$ exit
[[email protected] ~]$ echo $VAR1
deneme
Değişkeni global yapmak için ise export komutunu kullanıyoruz:
[[email protected] ~]$ export VAR1=deneme
[[email protected] ~]$ echo $VAR1
deneme
[[email protected] ~]$ ksh
$ echo $VAR1
deneme
$ exit
[[email protected] ~]$ 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:
[[email protected] ~]$ x=108
[[email protected] ~]$ name="John Locke"
[[email protected] ~]$ echo $name $x
John Locke 108
[[email protected] ~]$ export name
[[email protected] ~]$ ksh
$ print $x
$ print $name
John Locke
$ exit
[[email protected] ~]$
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:
[[email protected] ~]$ var=value
[[email protected] ~]$ export var
[[email protected] ~]$ var=value ; export var
[[email protected] ~]$ export var=value
[[email protected] ~]$ export x=108 y=549 z=4629
[[email protected] ~]$ echo $x
108
[[email protected] ~]$ echo $y
549
[[email protected] ~]$ 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:
[[email protected] ~]$ counter=1
[[email protected] ~]$ echo $counter
1
[[email protected] ~]$ echo ${counter}
1
${} gösteriminin başka yetenekleri de vardır. Bu yetenekleri aşağıdaki örneklerde
görmeye çalışalım:
[[email protected] ~]$ var=x
[[email protected] ~]$ echo ${var:-y}
x
[[email protected] ~]$ var=
[[email protected] ~]$ echo ${var:-y}
y
[[email protected] ~]$ unset var
[[email protected] ~]$ echo ${var:=y}
Bölüm 2
Kabuk
12 | S a y f a
İşletim Sistemleri
y
[[email protected] ~]$ echo ${var:=z}
y
[[email protected] ~]$ 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:
[[email protected] ~]$ for f in 4 8 15 16 23 42
> do
>
list=${list:+$list,}$f
> done
[[email protected] ~]$ 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:
[[email protected] ~]$ list="a
b
c d e
f"
[[email protected] ~]$ echo $list
a b c d e f
[[email protected] ~]$ 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:
[[email protected] ~]$ chmod +x first.sh
Artık çalıştırabiliriz:
[[email protected] ~]$ ./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
[[email protected] ~]$ . ./first.sh
Dosya sayisi (/home/student): 19
Katalog sayisi(/home/student): 16
b. source komutu ile çalıştırmak
[[email protected] ~]$ source ./first.sh
Dosya sayisi (/home/student): 19
Katalog sayisi(/home/student): 16
c. betik dosyasının adını vererek çalıştırmak
[[email protected] ~]$ ./first.sh
Dosya sayisi (/home/student): 19
Katalog sayisi(/home/student): 16
d. Kabuk komutu ile çalıştırmak
[[email protected] ~]$ 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:
[[email protected] ~]$ echo $VAR1
[[email protected]
[[email protected]
deneme
[[email protected]
[[email protected]
~]$ . ./second.sh
~]$ echo $VAR1
[[email protected]
[[email protected]
deneme
[[email protected]
[[email protected]
~]$ source ./second.sh
~]$ echo $VAR1
~]$ unset VAR1
~]$ echo $VAR1
~]$ unset VAR1
~]$ echo $VAR1
[[email protected] ~]$ ./second.sh
[[email protected] ~]$ echo $VAR1
[[email protected] ~]$ sh ./second.sh
[[email protected] ~]$ echo $VAR1
[[email protected] ~]$
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
[[email protected] ~]$ cat third.sh
#!/bin/sh
echo $$
[[email protected] ~]$ ps
PID TTY
TIME CMD
3819 pts/0
00:00:00 bash
9876 pts/0
00:00:00 ps
[[email protected] ~]$ echo $$
3819
[[email protected] ~]$ ./third.sh
9879
[[email protected] ~]$ . ./third.sh
3819
[[email protected] ~]$ source ./third.sh
3819
[[email protected] ~]$ 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.
[[email protected] ~]$ ls /nodir
ls: cannot access /nodir: No such file or directory
[[email protected] ~]$ echo $?
2
[[email protected] ~]$ 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
[[email protected] ~]$ echo $?
0
[[email protected] ~]$ true ; echo $?
0
[[email protected] ~]$ 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.
[[email protected] ~]$ export var="Hello Mars"
[[email protected] ~]$ 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.
[[email protected] ~]$ var=/usr/local/bin/example
[[email protected] ~]$ echo ${var%/*}
/usr/local/bin
[[email protected] ~]$ var=usr/local/bin/example
[[email protected] ~]$ echo ${var%%/*}
usr
[[email protected] ~]$ var=usr/local/bin/example
[[email protected] ~]$ echo ${var#*/}
local/bin/example
[[email protected] ~]$ var=usr/local/bin/example
[[email protected] ~]$ echo ${var##*/}
Example
[[email protected] ~]$ export var=abcdef
[[email protected] ~]$ echo ${var%${var#?}}
a
[[email protected] ~]$ echo ${var#${var%?}}
f
 ${var//PATTERN/STRING}
var değişkenindeki tüm PATTERN’leri STRING ile değiştirir.
[[email protected] ~]$ echo -e "${var}\n${var//?/~}"
Bölüm 2 - Kabuk
~~~~~~~~~~~~~~~
 ${var:OFFSET:LENGTH}
var değişkeninde OFFSET’ten itibaren LENGTH adet karakteri getirir
[[email protected] ~]$ export var=abcdefgh
[[email protected] ~]$ echo ${var:3:2}
de
Bölüm 2
Kabuk
16 | S a y f a
İşletim Sistemleri
[[email protected] ~]$ 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:
[[email protected] ~]$ echo "scale=8; a(1)*4" | bc -l
3.14159264
[[email protected] ~]$ echo "scale=16; a(1)*4" | bc -l
3.1415926535897932
[[email protected] ~]$ echo "scale=64; a(1)*4" | bc -l
3.1415926535897932384626433832795028841971693993751058209
749445920
[[email protected] ~]$ 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:
[[email protected] /]$ 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
[[email protected] /]$ 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:
[[email protected] /]$ 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 biri 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ü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."
Dizi kullanan örnek bir döngü uygulamasını inceleyelim:
#!/bin/ksh
for i in 1 2 3 4 5 6 ; do
((r= $RANDOM % 49 + 1))
numbers[$i]=$r
done
for j in ${numbers[*]} ; do
echo $j
done | sort -n
Bu örnekte, ilk for döngüsünde sayısal loto için 1-49 arasında altı sayı rastgele
olarak belirlenmekte ve numbers isimli dizide saklanmaktadır. İkinci for
döngüsünde ise numbers dizindeki değerler taranarak, sıralı olacak şekilde ekrana
yazılmaktadır. Sıralama işlemi için sort komutundan yararlanılmıştır. sort
komutunun sayısal değer olarak değerlendirmesi ve sıralaması için –n seçeneği
verilmiştir.
2.11 Fonksiyonlar
Çok sık karşılaşılan problemlerin çözümünü fonksiyon olarak ayrı bir dosyada
saklayabilirsek, aynı problemle tekrar karşılaştığımız betikte fonksiyonu çağırarak
çözüme hızlıca ulaşabiliriz. Fonksiyonlar betiklerimizden ayrı dosyalarda bir dizinde
Bölüm 2
Kabuk
19 | S a y f a
İşletim Sistemleri
saklanırlar. Bu dosyaların çalıştırma yetkisine de sahip olması gerekmez. Kabuğa,
fonksiyonların yer aldığı bu dosyaların dizinini, FPATH sistem değişkeni ile
tanıtıyoruz:
[[email protected] ~]$ mkdir fun
[[email protected] ~]$ export FPATH=$HOME/fun
Bu dizinde sadece fonksiyon dosyalarının olmasına dikkat etmelisiniz. Fonksiyon ismi
ile dosya ismi aynı olmalıdır.
Fonksiyonun genel yazımı aşağıdaki gibidir:
function hello
{
print “Merhaba $1”
}
Burada function anahtar kelimedir. Her fonksiyonun bir adı olmalıdır. Yukarıdaki
örnekte fonksiyonun adı hello’dur. Fonksiyonlar parametre alabilirler. Fonksiyonun
aldığı parametrelere erişmek için $ sembolünden yararlanıyoruz. İlk parametreye
ulaşmak için $1’i ikinci parametreye ulaşmak için ise $2 tanımlamasını kullanıyoruz.
Dokuzuncu parametreden sonra kıvırcık parantez kullanılmalıdır. Örneğin onuncu
parametre için ${10} gösterimi kullanılmalıdır.
[[email protected] fun]$ pwd
/home/student/fun
[[email protected] fun]$ ls
hello
[[email protected] fun]$ cat hello
function hello
{
print "Merhaba $1"
}
Şimdi hello isimli fonksiyonu kullanacağımız basit bir betik yazalım:
[[email protected] ~]$ cat test_hello.ksh
#!/bin/ksh
lost[1]="Jack Shephard"
lost[2]="Kate Austen"
lost[3]="James Ford"
IFS=,
for name in ${lost[*]}
do
hello $name
done
[[email protected] ~]$ ./test_hello.ksh
Merhaba Jack Shephard
Merhaba Kate Austen
Merhaba James Ford
Yukarıdaki örnekte lost dizisine üç değer atadık. Bu nedenle döngü üç defa döndü
ve hello fonksiyonu üç defa çalıştırıldı.
Bölüm 2
Kabuk
20 | S a y f a

Benzer belgeler