Unix'e Giriş
İşletim sistemlerinin kralı tartışmasız Unix. Geliştirilmesi 70'li yıllarda başlayan ve C programlama diline yakın oluşuyla daha da yayılan bu sistem çekirdeksel olarak şu anda cep telefonlar dahil olmak üzere milyarlarca makina üzerinde işliyor.
Süreçler
Unix'i Unix yapan pek çok kavram var. Kullanıcıya pek gözükmeyen sahne arkasındaki programları denetleyen, işleten çekirdek seviyesinde yaptıkları var, dosya / dizin bazında kullanıcıya gözüken kısmı var.
Unix'te süreç kavramı önemli. Her işleyen program bir süreç içinde
işler, diğerlerinden ayrı çevre değişkenleri, yerel hafıza bloğu
vardır (global hafızaya özel programlama ile erişilebilir). O anda
bilgisayarınızdaki işleyen süreçleri görmek için ps -eaf
işletebiliriz, mesela bende
burak 15316 15314 0 11:21 pts/0 00:00:05 mplayer -quiet -playlist http://
burak 15400 1 2 11:24 tty2 00:01:43 /usr/bin/emacs25
burak 16320 1 1 11:47 tty2 00:00:49 /usr/lib/firefox/firefox -new-wi
burak 16487 16320 0 11:47 tty2 00:00:26 /usr/lib/firefox/firefox -conten
root 17133 2 0 11:54 ? 00:00:01 [kworker/u8:2+ev]
listesi var. Hakikaten şu anda Emacs içindeyim, arka planda Firefox işliyor, vs. Bunların hepsi görülüyor. Bu süreçler yokedilebilir, vs., bkz Faydalı Unix Komutları.
Süreç listesini daha renkli olarak htop komutu ile görebiliriz (bağlantı altta).
Komut Satırı, Kabuk
Unix'te çoğu işlem komut satırı etrafında döner, en azından usta admin, kullanıcılar onu tercih eder. Programları başlatmak, idare etmek, gözetlemek için tercih edilir, script yazabilme ve onları işletebilme açısından komut satırı hep faydalı olmuştur. Görsel tıklamayı hatırlamak yerine istenen aksiyonu temsil eden birkaç harfi hatırlamak ve klavyede yazmak her zaman daha hızlıdır, bu açıdan 'bir resim bin kelimeye bedeldir' sözü Unix'te tepetaklak olmuştur, 'birkaç harf bin resme bedeldir' demek daha doğru olur.
Komut satırını başlattığımızda, mesela Ubuntu Linux'ta Terminal programı ile, bir süreç başlatılmıştır, ve bu süreç bir işler programın çağrılması ile olmuştur. Komut satırı başlatıyorum ve süreç listesine bakıyorum,
burak 14899 14890 0 11:20 pts/0 00:00:00 bash
görülüyor. Komut satırı, "kabuk (shell)" programı bu işte. Tabii komut
satırları tek tip değil, pek çok farklı program var, üstteki bash
,
ona has özellikleri var, ama sh
de var, ya da tsch
var,
vs. Terminale gidip
echo $SHELL
deyince
/bin/bash
cevabı alıyorum. Kabuk tipi orada tanımlı. Bu arada SHELL
bir çevre
değişkeni (environment variable), bir anlamda içinde olduğumuz sürecin
"çevresini" tanımlıyor, bu açıdan uygun isim. Çevre değişkenleri her
kabuk için farklı olabilir, birinden set ettiğimiz değişkeni
diğerinden göremeyebiliriz, ALI=veli
deyin, echo $ALI
bir veli
sonucunu verir, bir diğer bash ekranına gidin, aynı komut boş sonuç
verecektir.
Her bash
penceresinin başlangıç değerleri her kullanıcı için ana /
ev (home) dizindeki .bashrc
içinde set edilir. Dikkat, farklı kabuk
kullananlar için bu başlangıç dosyası farklı olur, mesela csh
için
.csh
.
Global ayarlar .bashrc
den önce işletilen (bash icin) /etc/profile
icindedir. Her kullanıcı başlangıçta yapılmasını istediği şeyleri
kendi .bashrc
'si içine koyabilir, admin her kullanıcı için
işlemesini istediği şeyler varsa onları /etc/profile
içine koyar.
Ev dizini her kullanıcı için ana dizindir, echo $HOME
ile ne
olduğunu görebilirsiniz, tek cd
komutu çoğu kabukta otomatik olarak
sizi ev dizine götürür. Ubuntu'da bu benim icin /home/burak
mesela.
Program Başlatmak
Kabuktan program başlattığımızda, mesela günün tarihi veren date
ile, satırda
$ date
dedik ve sonuç
Mon Jul 27 14:21:08 EEST 2020
geldi, bu komutu işlettiğimizde arka planda birkaç şey oldu. date
dedik ama hangi date? Bu programın işler kodunun olduğu dosya nerede?
Soru cevabı which date
ile alınabilir, cevap olarak /bin/date
geldi bizde. Hakikaten orada bir date
programı var,
$ ls -al /bin/date
-rwxr-xr-x 1 root root 100568 Jan 18 2018 /bin/date
Pek çok "sistem komutu" /bin/
altındadır bu arada. Peki sadece
date
deyince sistem /bin/date
işletmesini gerektiğini nasıl bildi?
Burada PATH
kavramı var, kabuk çevre değişkenleri içinde PATH
adlı
dizin listesi program işletince nerelere bakılması gerektiğini tanımlar,
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin...
Görüldüğü gibi /bin
dizini listede (sonda), ve bash
işletilmesi
istenen programı arayıp bu son dizinde buldu. PATH
değişkeni
başlangıç ayar dosyasında set edilir, bash
için .bashrc
ve
/etc/profile
.
Eğer karışıklığı meydan bırakmayacak şekilde bir programı direk
işletmek istersek bunu komut satırında /bin/date
yazarak
yapabilirdik. Hatta script yazarken tavsiye edilen yaklaşım budur.
Üstteki ls
sonucunun soldaki kısmı kafa karıştırmış olabilir,
-rwxr-xr-x
ne demek? Alttaki resimle anlatmaya uğraşalım,
En soldaki harf d
ise baktığımız şey bir dizindir, -
ise dosyadır.
Dikkat edersek kullanıcı (user) harfleri üç tane, grup (group) üç tane, diğerleri (other) üç tane. Bu harf üçlüleri, sırasıyla, o an olduğumuz kullanıcı, dahil olduğumüz grup ve diğerlerinin bu dosya üzerindeki izinlerini gösterir.
Hangi kullanıcı olduğumuzu id
ile hemen bulabiliriz.
Her harf öbeği rwx
olabilir, tabii bu harflerden bazıları iptal
olabilir, mesela -w-
olabilir. Harfler sırasıyla okuma (read), yazma
(write) ve işletme (execute) haklarını temsil eder. Yani üstteki
/bin/date
için gördüğümüz -rwxr-xr-x
kullanıcı (dosyanın sahibi
olan kişi) için rwx
diyor, yani tüm hakları vermiş, ama grup için
r-x
demiş, yani grup için yazma hakkı vermemiş.
Grup bu tür izinleri idare etmenin bir kolay yolu bir bakıma, her Unix
kullanıcısı admin tarafından birden fazla gruba atanmış
olabilir. Hangi gruba dahil olunduğunu her kullanıcı groups
komutunu
işleterek bulabilir. Grup atamaları /etc/groups
dosyası içinde
tutulur. Basit bir metin dosyasıdır, ama tabii ki herkes göremez,
sudo ls -al /etc/group
deyin,
-rw-r--r-- 1 root root 936 Jul 20 15:46 /etc/group
Dosya sahibi (admin) hariç başka kimsenin dosyaya yazma hakkı olmadığını görüyoruz.
İzinleri değiştirmek icin chmod kullanılır.
Pek çok şey kabuk etrafında döner dedik, program başlatmak bunlardan
en önemlisi. Bir program ismini yazarak onu komut satırından
başlatırız, ama o programı arka plana atarak ta işletebiliriz. Burada
&
işareti devreye girer, mesela xclock
desem grafik saat programı
başlar ama onu başlattığım komut satırının "bloklanmış" olduğunu
görebilirim çünkü başlatan program başlatılanın bitmesini
bekliyor. Programı üst sağ köşesindeki kapatma düğmesinden kapatırsam,
ya da başlatan kabuktan Ctrl-C ile durdurursam, ya da başka bir
pencereden kill -9
ile, o zaman kabuğa geri dönüldüğünü
görürüm. Eğer bu bloklamanın olmasını istemiyorsak, en başta xclock
&
işletebilirdik, bu xlock
programını arka plana atar, hemen geri
döner, bekleme olmaz, böylece ana kabukta hala başka komutlar
işletebilir halde oluruz.
Ama dikkat, her süreç başlattığı sürecin ebeveyni haline gelir, &
ile başlatsak bile başlatan ebeveyn durumundadır, eğer başlatan süreç
ölürse, başlatılan da ölür. Mesela bir konsol komut satırı başlattım,
oradan emacs &
ile editörü başlattım, konsolu kapatırsam, emacs
programı da kapanacaktır. O zaman başlatanda "evlatlık reddi" yapmak
lazım, yani emacs & disown
. O zaman aradaki bağlantı kopar, başlatan
ölürse başlatılan ölmez.
Başlangıç Ayarları
Komut satırı metin bazlı bir ortam olduğu için eğer bazı komutları sürekli
klavyede giriyorsak onları kısa temsil eden bir kısayol (alias) yaratmak
faydalı olabilir. Mesela sürekli ssh user1@192.168.44.33
ile bir makinaya
ssh girişi yapıyorum, bu komutu
alias myssh='ssh user1@192.168.44.33`
ile özetleyebilirim. Artık myssh
yazınca belirtilen ssh
komutu
işler. Bir alias sonrası gelen seçenekler, ek komutlar alias açılımı
sonuna eklenir, eğer myssh -X
diyorsam bu komut ssh user1@192.168.44.33 -X
olarak açılacaktır.
Peki ya alias ortasına bir ek parametre geçmek istesem? Diyelim ki standard
bir fınd /usr -name '*.txt'
komutu uyguladım, fakat aramanın başladığı
dizini /usr
değil bir değişken üzerinden tanımlamak istiyorum. Bu durumda
düz alias işlemez, ama bir bash fonksiyonu işler,
function myfind() {
find "$@" -name '*.txt'
}
Bu kısayolu myfind /tmp
şeklinde kullanabilirim, verdiğim parametre fınd
komutunun "$@"
kısmına enjekte edilecektir.
Yukarı