Sisteme girdiğiniz anda kabuk programının çalıştırıldığından bahsetmiştik. Bu andan sonra yapacağınız tüm işlemler bu kabuk programı tarafından yönetilir ve denetlenir. Kabuk, klavyeden girilen komutları çalıştırarak bir arabirim görevi yapar. UNIX (ve Linux) altında geliştirilen sayısız kabuk çeşidi ve bunların herbirinin kendine ait özelliği vardır. Her programcı kendi zevkine hitap eden kabuğu seçebilir, sistemde yeralan kullanıcılar farklı kabuklar üzerinde çalışabilirler.
O an hangi kabuk üzerinde yeraldığınızı öğrenmek için
echo $SHELL
yazın.
$ echo $SHELL /bin/bash
Sıkça kullanılan kabuklar,
sh (Shell ya da Bourne Shell): İlk UNIX kabuğu.
ksh (Korn Shell): sh uyumlu, birçok ek programlama özelliği içeren bir kabuk. Bu kabuk da yaygın bir kitle tarafından kullanılıyor.
bash(Bourne Again Shell): Kullanım kolaylığı bakımından en çok rağbet gören bash, GNU tarafından kaynak kodu olarak dağıtılıyor. bash sh ve ksh uyumluluğunu korurken, özellikle etkileşimli kullanıma yönelik (komut tamamlama, gibi) birçok yenilik de içerir. Bu yazının hazırlandığı 1997 Temmuz ayı başlarında Bash 2.0.1 sürümü çıkmıştı.
csh (C shell): Berkeley Üniversitesi'nde geliştirilen csh'in C diline benzer bir programlama yapısı vardır.
tcsh: csh'ın biraz geliştirilmiş hali.
Yukarıdaki kabuk programlarından sh, ksh ve bash
birbirleriyle
uyumludur ve yukarıda en ilkelden en gelişmişe göre sıralanmışlardır.
Aynı durum csh ve tcsh
için de geçerlidir. Kullanılan shell
genellikle kişisel bir tercih nedeni olsa da, bütün sistem scriptleri
sh
ile yazıldığından, sistem yöneticilerine sh
ailesinden bir
kabuk kullanmaları önerilir.
Kabuk programları genellikle /bin
dizini altında
yeralır. Kullanıcının sisteme girerken hangi kabuğu kullanacağı
/etc/passwd
dosyasında yeralır. Bunu değiştirmek için
chsh
(change shell) komutunu kullanabilirsiniz.
$ chsh Password: Changing the login shell for cagri Enter the new value, or press return for the default Login Shell [/bin/sh]: /bin/bash $
Sisteminizde NIS kullanılıyorsa chsh
yerine yppasswd -s
komutunu kullanmalısınız.
Kullanıcı, ekrana yazdığı bir komutun neler yaptığını en rahat şekilde komut tarafından ekrana yönlendirilen bilgilerden anlayabilir. Program, kullanıcıyı bilgilendirme amacıyla mümkün olduğu kadar çok, fakat ortalığı fazla karıştırmamak için de mümkün olduğu kadar az bilgiyi ekrana vermelidir.
Linux'ta, programın ekrana yazılan bilgiyi iki sınıf altında toplayabiliriz. Birincisi, olağandışı bir durumu bildiren standart hata, diğeri de her türlü verinin yazıldığı standart çıktı. Program çalıştığı andan itibaren bu iki kanal üzerinden akan bilgiler, programın çalıştığı sanal terminale yazılırlar. Program girdilerini ise standart girdi aracı olan klavyeden alır.
Eğer bu bilgiler bir ekran boyundan (25 satır) fazla tutuyorsa bazı
satırlar programcının gözünden kaçabilir. Bunu önlemek amacıyla standart
çıktı ve hata bir dosyaya yazılacak şekilde ayarlanabilir. Yönlendirme
olarak da bilinen bu işlem UNIX altında (DOS'ta olduğu gibi) >
karakteri ile gerçekleştirilir.
Örnek olarak o an bulunduğunuz dizinde yeralan dosyaları ekrana getirin :
$ ls -al
Bu komut, standart çıktı olarak dosyaların bilgilerini ekrana getirecektir. Bu çıktıyı, bir dosyaya yönlendirelim ve dosyanın içeriğine göz atalım:
linux:~$ ls -al > liste linux:~$ cat liste total 16 drwxr-xr-x 5 gorkem users 1024 Feb 13 13:10 . drwxr-xr-x 4 root root 1024 Jan 7 1980 .. -rw-r--r-- 1 gorkem users 390 Feb 13 12:56 .Xdefaults -rw-r--r-- 1 gorkem ftpadm 2016 Feb 13 13:09 .bash_history -rw-r--r-- 1 gorkem users 1 Feb 13 12:57 .bashrc -rw-r--r-- 1 gorkem users 163 Nov 24 1993 .kermrc -rw-r--r-- 1 gorkem users 34 Nov 24 1993 .less -rw-r--r-- 1 gorkem users 114 Nov 24 1993 .lessrc drwxr-xr-x 2 gorkem users 1024 Jan 7 1980 .term -rw-r--r-- 1 gorkem users 87 Feb 13 12:56 .xinitrc -rw-r--r-- 1 gorkem users 2795 Feb 13 13:06 adres -rw-r--r-- 1 gorkem users 0 Feb 13 13:10 liste drwxr-xr-x 2 gorkem users 1024 Feb 13 12:54 mail drwxr-xr-x 2 gorkem users 1024 Feb 13 12:54 perl -rw-r--r-- 1 gorkem users 0 Feb 13 13:10 typescript linux:~$
>
karakteri standart hatayı dosyaya yönlendirmez. Bu işlem için
2>
kullanılır. Ama hatayı görebilmek için, hata yaratan bir
komut yazmalıyız, değil mi ?
$ ls /deneme /deneme : No such file or directory $ ls /deneme 2> hata $ cat hata /deneme : No such file or directory
Aşağıdaki komutun işletilmesinin ardından standart çıktı oku1
dosyasına,
standart hata ise oku2
dosyasına yazılacaktır. Bu dosyaları komutu
çalıştırdıktan sonra incelemek suretiyle neler olup bittiğini anlamak
mümkün olur.
$ mkdir ~/deneme (deneme isimli bir dizin yarat) $ touch ~/deneme/gecici (gecici isimli bir dosya yarat) $ cat ~/deneme 2>oku2 >oku1
Kabuk, standart çıktı ve standart girdi için sırayla 2 ve 1 numaralarının
kullanımına izin verir. Yukarıda yeralan son komutta, standart
hata mesajları için 2 kullanılarak hataların oku2
dosyasına
yazılmıştır. Aşağıda, çekirdek derlemek için sürekli kullandığım
program yeralıyor. Yönlendirme sayesinde ekrana gelmesi gereken mesajlar
kullanılmayan 9. sanal konsola yönlendiriliyor.
# make config # make dep > /dev/tty9 # make clean > /dev/tty9 # time make zImage > /dev/tty9
Son satırdaki time
komutu, kendinden sonra gelen komutun ne kadar
zaman içinde çalıştırıldığını gösterir. Çekirdek derlemede geçen zaman,
makinanın gücü hakkında bir fikir verebilir. Peki ne hata, ne de çıktıyı
ekranda görmek istemiyorsam ne yapmalıyım ? Bunun için standart çıktı
ve hatayı biraraya getirerek yönlendirilen her çıktının kaybolduğu
``kara deliğe'' atmak yeterlidir:
$ ls /deneme > /dev/null 2>&1
Yukarıdaki komutun yazılış sırasına dikkat edin.
Standart çıktı ya da standart hatayı yönlendirirken, >
işareti kullanırsanız: dosya yoksa, oluşturulur ve komutun çıktısı dosyaya
yazılır. Dosya varsa, içeriği yok olur, ve komutun çıktısı dosyanın yeni
içeriği olur. Var olan bir dosyayının eski içeriğini tamamen silmek
değil de komutun çıktısını dosyaya eklemek istiyorsanız >>
kullanmalısınız. Bu durumda dosya varsa komutun çıktısı dosyanın eski
içeriği korunarak sonuna eklenir, dosya yoksa oluşturulur ve komutun
çıktısı dosyaya yazılır. Örneğin:
$ echo deneme1 >>deneme.txt $ cat deneme.txt deneme1 $ echo deneme2 >>deneme.txt $ cat deneme.txt deneme1 deneme2 $
Örnekte görüldügü gibi ilk komut deneme.txt
dosyasını oluşturdu. İkincisi ise oluşan dosyanın içeriğini koruyarak ikinci komutun çıktısını bu dosyanın sonuna ekliyor.
Standart hata ve çıktıya ek olarak UNIX'in desteklediği bir yönlendirme daha vardır: Standart girdi sayesinde bir dosyayı oluşturan satırlar, bir komut veya programa yönlendirilebilir. Daha önce bir metin editor kullanarak hazırlamış olduğumuz raporu patrona kısa yoldan göndermek için,
$ mail -s "rapor" patron < rapor.txt
Dosyanın içeriği, mail komutuna girdi olmuş ve rapor.txt
dosyası
patron
kullanıcısına ``rapor'' konu başlığıyla e-posta ile
gönderilmiştir.
Bazı durumlarda, bir komutun çıktısı diğer bir komuta yönlendirilebilir. Başka bir deyişle, komutun standart çıktısını bir dosyaya değil, bu çıktıyı işleyecek başka bir komuta yönlendirmek istiyorsunuz. Bu amaçla UNIX altında (yine DOS'ta olduğu gibi) boru (|) karakteri kullanılır. Bu karakter, kendinden önce gelen komut veya komut serisinin çıktısını, kendinden sonra gelen komuta gönderir. Örneğin bir dizinde yeralan tüm dosyaları yazıcıya aktarmak için,
$ ls -al | lpr
komutları kullanılabilir. Artık ls -al
komutunun ekrana vermesi gereken
tüm bilgiler, lpr
komutu aracılığıyla yazıcıya gönderilmiştir. İlk komutun
standart çıktısı, ikinci komuta standart girdi olarak atanır. Diğer bir
örnekte, README
dosyasında kaç satır olduğu bulunuyor. Bir dosyadaki
veya komut çıktısındaki satır, karakter ve kelime sayılarını bulmak için wc
komutunu
kullanabilirsiniz.
$ who | wc -l 40
Yönlendirme ve pipe işlemleri bazen insanın kafasını karıştırabilir. Yönlendirme, bir programdan bir dosyaya yapılabilir, fakat bir programdan başka bir programa yönlendirme yapamazsınız. Benzer şekilde, iki dosyanın arasında pipe işlemi uygulamak mümkün olmaz.
Şimdi de biraz karışık bir örnek:
# ps -aux | grep inetd | grep -v grep|awk '{print $2}' | xargs kill -1
Yukarıdaki örnek zorlama bir örnek değil, bir Linux sistem yöneticisinin her an kullanması gerekebilecek türden. Bu örneği burada ayrıntılı olarak açıklamayacağız, sadece pipe kullanarak ne kadar fazla sayıda komutun birbirine bağlanabildiğini göstemek amacıyla verdik. Bu ve benzeri komutların ayrıntılı açıklamaların kabuk programlamayla ilgili bölümde bulabilirsiniz.
UNIX'in en büyük silahlarından biri süreçlerdir. Her süreç sistemde bağımsız çalışan, birbirini etkilemeyen ve herbiri kendi kaynağını kullanan programdır. Süreçler arkaplanda veya kabuğun kontrolünde çalışabilir. Çekirdek, her sürecin kullandığı sistem kaynağından haberdar olur ve bu kaynakların süreçler arasında adilce paylaşılmasından sorumludur.
Bir süreç, aksi belirtilmedikçe çalıştığı süre içinde klavyeden bilgi alır ve ekrana bilgi verir.
Kullanıcıların haberi bile olmadan çalışan süreçler, Linux makinasındaki G/Ç işlemlerini gerçekleştirebilmek için sürekli faaliyet içinde bulunurlar. Onlarca süreçten bazıları kullanıcıların sisteme girmesini sağlarken (getty) bazıları da WWW ve FTP gibi İnternet tabanlı istekleri yerine getirir (httpd, ftpd).
Bir komutu arkaplanda çalıştırmak için, komutun sonuna &
karakteri
getirin. Komutu girdikten sonra tekrar kabuk istemcisine düşecek ve kaldığınız
yerden devam edebileceksiniz. Program, arkaplanda diğer süreçlerle
çakışmadan bir süre çalışır ve işi bittiğinde durur.
$ sort buyuk_dosya > buyuk_dosya.sirali & [1] 772
Komutun arkaplana atılmasından sonra ekranda yeralan
Çalışan programların listesini görmek için ps
komutunu kullanın. Hiç
parametre vermeden yazılırsa sadece üzerinde çalışılan kullanıcının
süreçleri ekrana gelir. Sık kullanılan bir başka parametre dizisi de uax
tir. Bu sayede sistemdeki o anda çalışan tüm programlar daha ayrıntılı
bir şekilde ekrana listelenir.
$ ps PID TTY STAT TIME COMMAND 76 v02 S 0:00 -bash 111 v02 R 0:00 ps
$ ps -aux USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND bin 63 0.0 5.5 64 364 ? S 11:12 0:00 /usr/sbin/rpc.portmap gorkem 76 0.0 9.7 101 644 v02 S 11:12 0:00 -bash gorkem 112 0.0 5.0 59 332 v02 R 11:16 0:00 ps -aux root 1 0.0 5.0 56 332 ? S 11:12 0:00 init [5] root 6 0.0 4.2 35 284 ? S 11:12 0:00 bdflush (daemon) root 7 0.0 4.2 35 284 ? S 11:12 0:00 update (bdflush) root 48 0.0 5.1 45 340 ? S 11:12 0:00 /usr/sbin/crond -l10 root 59 0.0 5.5 53 364 ? S 11:12 0:00 /usr/sbin/syslogd root 61 0.0 5.0 44 336 ? S 11:12 0:00 /usr/sbin/klogd root 65 0.0 5.5 62 364 ? S 11:12 0:00 /usr/sbin/inetd root 67 0.0 5.8 79 388 ? S 11:12 0:00 /usr/sbin/rpc.mountd root 69 0.0 6.0 88 400 ? S 11:12 0:00 /usr/sbin/rpc.nfsd root 75 0.1 9.9 115 660 v01 S 11:12 0:00 -bash root 77 0.0 4.6 52 304 v03 S 11:12 0:00 /sbin/agetty 38400 tty3 root 78 0.0 4.6 52 304 v04 S 11:12 0:00 /sbin/agetty 38400 tty4 root 79 0.0 4.6 52 304 v05 S 11:12 0:00 /sbin/agetty 38400 tty5 root 80 0.0 4.6 52 304 v06 S 11:12 0:00 /sbin/agetty 38400 tty6 root 81 0.0 5.5 42 368 ? S 11:12 0:00 gpm -t ms
Burada yeralan bilgiler sırasıyla :
SIZE
değerinden küçüktür.Control-Z
tuşlarına basılarak)
durdurulmasında görülür.ps
komutuna bilgisayar üzerinde çalıştığınız her an ihtiyaç duymanız
mümkündür, bu yüzden çeşitli parametrelerle kullanmayı öğrenmelisiniz.
Linux (ve UNIX) altında, klavyeden bazı tuş kombinasyonları yardımıyla çalışmakta olan program kesintiye uğratılabilir.
Klavyeden kabuk komut satırına yazılan bir programın uzun sürmesi halinde,
eğer daha önceden komutun arkasına &
işareti koyup arkaplanda çalışır
halde bırakılmamışsa, klavyeden yapılan bir müdahele ile durdurulup
arkaplanda çalışır hale getirilebilir. Örnek vermek gerekirse, uzun
sürmesi beklenen bir komutu klavyeden yazalım ve ardından Control-Z
tuşlarına basalım:
linux:/etc/rc.d# find /usr -name "o*" -print /usr/bin/od /usr/lib/lilo/doc/other.fig /usr/lib/lilo/doc/other.tex /usr/man/man1/od.1.gz [1]+ Stopped find /usr -name "o*" -print linux:/etc/rc.d#
Bu esnada sürecin çalışmasına ara verilmiş, fakat program tamamen
durmamıştır. Programın çalışmasını arkaplanda sürdürmek için bg
komutunu kullanın.
$ bg
Bu komutu tekrar komut satırında çalışacak ve klavyeden bilgi girilecek
şekilde terminale bağlamak için fg
yazın:
$ fg
Bir programı çalıştırmaya başlattıktan sonra tamamen durdurmaya karar
vermişseniz klavyeden Control-C
tuşlarına basın.
Durdurulup arkaplanda çalışmaya yönlendirilen süreçlere kısaca görev ismi verilir. Tüm görevleri görebilmek için
$ jobs
yazın. Görevler, birden fazla oldukları zaman sıra numarası ile belirtilirler.
Her an çalışan süreçlerden biri veya birkaçı, beklenmedik döngüye
girebilir. Bunun sonucu olarak sistemin kaynaklarını, özellikle hafızayı
tüketici bir duruma gelebilir. Bu tür kısır döngüye giren süreçleri bulup,
eğer hayati önem taşımıyorlarsa `öldürmek' gerekir. Süreci öldürmekten
kasıt, programı tamamen durdurarak sistemle ilişkisini kesmektir. Bu
sayede programın hafızada kapladığı bölge serbest kalacak, çekirdek
de hafıza düzenlemesini tekrar yaparak başka süreçlere daha fazla yer
ayıracaktır. Bir süreci öldürmek için kill
komutu kullanılır.
Yukarıdaki 67 numaralı sürece ait /usr/sbin/rpc.mountd
programını öldürmek için şunları yazın :
$ kill 67
Birçok süreç sizden bu mesajı aldıktan sonra, dosya sistemi üzerinde yarattığı geçici dosyaları, dosyalar üzerine koyduğu kilitleri temizlemek gibi yapması gereken işlemleri yaptiktan sonra çalışmasına son verecektir. Eğer öldürmeye çalıştığınız süreç herhangi bir nedenle takılmışsa ve bu komuta tepki vermiyorsa aşağıdakini deneyin:
$ kill -9 67
Artık programın sistemle ilişkisi tamamen kesilmiştir. Kill komutu,
-9
seçeneğiyle sürece 9 numaralı sinyali gönderir. Bu sinyali
alan sürecin yukarıda sözü edilen iki özel durum dışında çalışmayı
sürdürmesi olanaksızdır. -9
seçeneğini özellikle sistem süreçleri
üzerinde gerekmedikçe kullanmamalısınız. Diğer sinyaller ve anlamları
yeri geldikçe diğer bölümlerde anlatılacaktır.