The source code for this blog is available on GitHub.

X Technology.

İkinci Ders Teknolojiye Giriş | X-Akademi

Cover Image for İkinci Ders Teknolojiye Giriş | X-Akademi
Ahmet İnanç Koca
Ahmet İnanç Koca
Posted underBilişim SistemleriLinux

Bu serinin devamı niteliğinde ki ana terimleri incelememiz devam ediyor. İlk bölümü okumadıysanız lütfen aşağıda ki linkten okumayı ihmal etmeyin.

https://blog.xtechnology.co/posts/gelecek-teknolojiye-giris

Birinci Ders – Teknolojiye Giriş

Önceden Tanımlanmış Değişkenler

Kabuk tarafından dahili olarak ayarlanan ve kullanıcıya sunulan bazı değişkenler vardır:
1$ – $9: Konumsal parametreler
$0: Komut adı
$#: Konumsal argümanların sayısı
$? : Yürütülen son komutun çıkış durumu ondalık dizgesi (0,1,2 ..) olarak verir.
$$: Eşsiz(unique) dosya isimleri oluşturmak için yararlı olabilen, çalışılan kabuğun süreç(process) numarası.
$! : Arka planda çalışan son komutun işlem kimliği (Son arka plan işleminin PID’sini tutar).
$- : Kabuğun bu çağrısına uygulanan tedarik edilmiş mevcut seçenekler.
$* : $1 ‘dan başlayan, kabuğun tüm argümanlarını içeren bir dize.
$@: Alıntılananlar hariç, yukarıdakiyle aynı.

Not: ∗ve @ alıntı yapıldığında aynıdır ve değişkenlere genişler.
“$*”, boşlukla birleştirilmiş, kabuğun tüm argümanlarını içeren tek bir kelimedir. Örneğin, ‘1 2’ 3 , “1 2 3” olur.
“$@”, kabuk tarafından alınan argümanlarla aynıdır, sonuçta ortaya çıkan sözcük listesi, kabuğa verilenlerle tamamen eşleşir. Örneğin, ‘1 2’ 3 , “1 2” “3” olur.

Argümanları komut dosyalarına geçirme

Standart UNIX komutları gibi, kabuk komut dosyaları(shell scripts)’da komut satırından değişken alabilir.
Bağımsız değişkenler, komut satırından $1 ile $9 arasındaki konumsal parametreler kullanılarak bir kabuk programın içine geçirilir.
$0 konum parametresi, komut adını veya kabuk komut dosyasını içeren yürütülebilir dosyanın adını belirtir.
Tüm konumsal parametreler $* özel parametresi kullanılarak ifade edilebilir.

Examples

$ cat pass_arg.    # 5 sayı kabul eden ve toplamını gösteren bir script.
aktarılan parametrelerin gösterimleri(echo ile) : $1, $2, $3, $4, $5
betiğin adının gösterimi (echo ile) : $0
aktarılan parametrelerin sayısı(echo ile) : $#
sum=`expr $1 + $2 + $3 + $4 + $5`
toplamları : $sum

shift komutu

Bir komut dosyasına 9’dan fazla parametre iletilirse, parametrelere erişmek için iki alternatif vardır:

Notasyonu ${n}
shift komutu

Shift komutu parametreleri bir konum sola kaydırır.
Shift komutunun yürütülmesinde, ilk parametrenin üzerine ikincisi yazılır, ikinci’nin üzerine üçüncü yazılır ve bunun gibi devam eder.

Örnek;

Farklı sayıları kabul edecek ve toplamlarını bulacak bir komut dosyası yazalım. Parametrelerin sayısı değişebilir.

$ cat sum_arg
sum=0
while [ $# -gt 0 ]
do
     sum=`expr $sum + $1`
     shift
done
echo sum is $sum

Örnek; Bu örneği birtane script dosyasının içine yazıp daha sonra sh script.sh 1 2 3 4… şeklinde parametreler vererek terminalden çağırıp deneyebilirsiniz.

#!/bin/bash
echo “arg1=$1 arg2=$2 arg3=$3”
shift
echo “arg1=$1 arg2=$2 arg3=$3”
shift
echo “arg1=$1 arg2=$2 arg3=$3”
shift
echo “arg1=$1 arg2=$2 arg3=$3”

Null komutu

Kabuk yerleşik bir null komutuna sahiptir

formatı basit;

  • :

Amaç hiçbir şey yapmamak

Genellikle bir komutun, özellikle de komutlarda görünmesi gerekliliğini yerine getirmek için kullanılır.

if grep “^$system” ~/mail/systems > /dev/null
then
    :
else
    echo “$system is not a valid system”
    exit 1
fi
Kabuk, bundan sonra bir komut yazmanızı gerektirir. Sistem geçerliyse, hiçbir şey yapılmaz

&& ve || operatörleri

Kabuk, bir önceki komutun başarılı veya başarısız olmasına bağlı olarak bir komutu çalıştırmanıza olanak tanıyan iki özel yapıya sahiptir.

&& operatörü eğer önceki komut başarılı bir şekilde derlenirse sonraki komutu uygular.

  • komut1 && komut2

komut2 yalnızca komut1 sıfır çıkış durumunu döndürürse çalıştırılır.
örnek;
[ -z $EDITOR ] && EDITOR=/bin/ed

|| operatörü eğer önceki komut başarısız bir şekilde derlenirse sonraki komutu uygular.

  • komut1 || komut2

komut2 yalnızca komut1 sıfır olmayan bir çıkış durumu döndürdüğünde çalıştırılır

Örnekler;
[ -z $PATH ] || echo $PATH
grep “$name” phonebook || echo \
“Not found $name“
who | grep “^$name ” > /dev/null || echo \
“$name’s not logged on“

(Satırın sonunda \ kullanıldığında, kabuğun satıra devam ettiğini bildirir.)

&& ve || Aynı komut satırında da birleştirilebilir:

who | grep “^$name ” > /dev/null && \
echo “$name is logged on” || echo “$name’s \
not logged on”

Grep başarılı olursa ilk echo gerçekleşir;başarısız olursa ikinci echo.

Bu operatörler if komutları ile temsil edilebilir.

if grep “$name” phonebook
then
    :
else
    echo “Couldn’t find $name“
fi

Koşullu İfadeler

Her Unix komutu, çıkışta kabuğun sorgulayabileceği bir değer döndürür. Bu değer salt okunur kabuk değişkeni $? İçinde tutulur.

0 (sıfır) değeri başarıyı gösterir; 0 (sıfır) dışında herhangi bir şey başarısızlık anlamına gelir.

Tamsayı kullanıyorsanız: ((koşul))
Dizeler kullanılıyorsa: [[koşul]]
Çıkış durumları duruma bağlı olarak sıfır veya sıfır değildir
Örnekler:
(( a == 10 ))
(( b >= 3 ))
[[ $1 = -n ]]
[[ ($v != fun) && ( $v != games) ]]
(( Z > 23 )) && echo Yes

Dosya varlığı, dosya izinleri, sahiplik, dosya türü vb. İçin özel koşullar.

  • [[ -e $file ]] –File exists? (dosya mevcut mu?)
  • [[ -f $file ]] –Regular file? (dosya normal mi?)
  • [[ -d $file ]] –Directory? (dizin mi?)
  • [[ -L $file ]] –Symbolic link? (sembolik link?)
  • [[ -r $file ]] –File has read permission? (dosya okuma izni varmı)
  • [[ -w $file ]] –File has write permission? (dosya okuma yazma varmı)
  • [[ -x $file ]] –File has execute permission? (dosya çalıştırma izni varmı)
  • [[ -p $file]] –File is a pipe?

İf deyimi

İf ifadesi verilen komutun çıkış durumunu kullanır ve şartlı olarak aşağıdaki ifadeleri çalıştırır.

Genel sözdizimi:
if koşul
then
    komutlar (koşul doğruysa)
else
    komutlar (koşul yanlışsa)
fi

İç içe if ifadesi:
if (—–)
then …
else if …
    …
  fi
fi

elif ifadesi, else if ifadesi için kısa yol olarak kullanılabilir.

örnek:
if [[ -r $fname ]]
then
    echo “$fname is readable”
elif [[ -w $fname && -x $fname ]]
then
    echo “$fname is writeable and executable”
fi

test komutu

Unix sistemi, önceki komutun çıkış durumunu araştıran ve sonucu başarı ya da başarısızlık biçiminde çeviren, yani sonucu 0 ya da 1 olan test komutu sağlar.

Test komutu herhangi bir çıktı üretmez, ancak testin başarısız olup olmadığını kontrol etmek için çıkış durumu if ifadesine geçirilebiliriz.

Herhangi bir komutun çıkış durumunu nasıl öğrenebilirim?

Tüm komutlar çıkış durumunu, echo komutu kullanılarak görüntülenebilen önceden tanımlanmış bir Shell Değişkenine ‘?’ Döndürür. Örneğin;
echo$?
Bunun çıktısı 0 (Sıfır) ise önceki komut başarılı olmuş demektir veya çıktı 1 (Bir) ise önceki komutun başarısız olduğu anlamına gelir.

Test komutunun aşağıda açıklanan dosyalar, sayısal değerler ve diziler üzerinde çalışması için belirli operatörleri vardır: Test komutuyla kullanılan Sayısal

Değişkenlerdeki İşleçler:

  • -eq : equal to(eşittir)
  • -ne : not equals to(eşit değildir)
  • -gt : grater than (dan büyüktür)
  • -lt : less than (dan küçüktür)
  • -ge : greater than or equal to(büyük veya eşittir)
  • -le : less than or equal to(küçük veya eşittir.)

Test komutuyla kullanılan String Değişkenleri işleçleri:

  • = : equality of strings(dizgelerin eşitliği)
  • != : not equal (eşit değil)
  • -z : zero length string (sıfır karakter içeren dize yani null dize).
  • -n : String length is non zero.(dize uzunluğu sıfır değil)

Örnekler:
$> a=12; b=23
$> test $a –eq $b
>echo?      # 1verir
$> name=”Ahmet”
$> test –z $name      #return 1
$> test –n $name      #return 0
$> test –z “$address”
$> test $name = “Ali”

Test komutuyla kullanılan dosyalardaki operatörler:

  • -f: dosya var.
  • -s: dosya var ve dosya boyutu sıfır değil.
  • -d: dizin var.
  • -r: dosya var ve okuma iznine sahip.
  • -w: dosya mevcut ve yazma iznine sahip.
  • -x: dosya var ve yürütme iznine sahip.

Örnekler:
$> test –f “mydoc.doc”
# mydoc.doc dosyasını kontrol eder, varsa 0, yoksa 1 döndürür.
$> test –r “mydoc.doc”
# mydoc.doc için okuma izni olup olmadığını denetler
$> test –d “$HOME”
# kullanıcıların ana dizininin varlığını kontrol eder..

Test komutuyla kullanılan Mantıksal Operatörler:

Birden fazla koşulu birleştirmek mantıksal AND, OR ve NOT işleçleriyle yapılır.

  • -a: mantıksal AND(VE)
  • -o: mantıksal OR(VEYA)
  • ! : mantıksal NOT(DEĞİL)

$> test –r “mydoc.doc” –a –w “mydoc.doc”
# mydoc.doc dosyasının hem okuma hem de yazma iznini kontrol eder ve sonucA bağlı olarak 0 veya 1 döndürür.

if who | grep -s hakan > /dev/null
then
    echo hakan CE sunucusuna giris yapti
else
    echo hakan CE sunucusunda mevcut degis
fi

Bu script, şu anda sisteme giriş yapmış olan kişileri listeler ve çıktıyı grep üzerinden pipe ile yönlendirir.

durum(case) açıklamaları

Sözdizimi:
case expression in
  pattern1)
    commands ;;
  pattern2)
    commands ;;
… *)
    commands ;;
esac

örnekler:
örnek1:
case $1 in
-a)
    a seçeneğiyle ilgili komutlar ;;
-b)
    b seçeneğiyle ilgili komutlar ;;
*)
    diğer tüm seçenekler ;;
esac

örnek2:
clear
echo “1. Date and time”
echo
echo “2. Directory listing”
echo
echo “3. Users information “
echo
echo “4. Current Directory”
echo
echo –n “Enter choice (1,2,3 or 4):”

örnek3:

read choice
case $choice in
    1) date;;
    2) s -l;;
    3) who ;;
    4) pwd ;;
    *) echo wrong choice;;
esac

bu komutları birtane script dosyasının içine yazıp bu dosyayı terminalden çalıştırdığımız zaman bizden birtane argüman ister bu argümanı okuduktan sonra 1,2,3,4 veya diğer olacak şekilde ayırarak farklı komutları çalıştırır.

for döngüsü

Sözdizimi:
for var [in list ]
do
     commands
done

Tek bir satırdaki komutlar noktalı virgülle (;) ayrılır.
Liste belirtilmezse, $@ kabul edilir.
Aksi takdirde ${list [*]} , Burada liste bir dizi değişkenidir.

örnekler:

for colors in Red Blue Green Yellow Orange Black Gray
  do
    echo $colors
  done
echo

Bu örnek verilen tüm renkleri terminale yazdırır.

While döngüsü

Sözdizimi:
while command-list1
do
   command-list2
done

command-list1’deki son komutun çıkış durumu 0 (sıfır) ise, command-list2’deki komutlar yürütülür.

Anahtar kelimeler break, contiune ve return , C / C ++ ile aynı özelliklere sahiptir.

break [num] veya contiune [num] # num döngü sayısıdır

Until döngüsü

Sözdizimi:
Until command-list1
do
   command-list2
done

Döngü, command-list1’in çıkış durumu sıfır olmadıkça gerçekleştirilir.

While/until komutunun çıkış durumu, command-list2’de yürütülen son komutun çıkış durumudur. Eğer böyle bir komut listesi çalıştırılmazsa, while/until çıkış 0 durumundadır.

örnekler:

eval komutu

… (Bölüm 7 henüz bitmedi devam edicek :))

Bölüm-8 Gelişmiş Kabuk Betiği(Advanced Shell Scripting )

Fonksiyon oluşturma ve kullanma

Bir kabuk fonksiyonunun tanımı aşağıdaki gibidir:
isim(){list ;}

Geçerli ve geçersiz fonksiyon tanımları: lsl(){ ls -l ; }     # geçerli
lsl { ls -l ; }     # geçersiz

sh için takma ad tanımlama:
$> cat mycd
cd () { chdir 1:−$HOME;PS1=”‘pwd‘ ” ; export PS1 ; }
$> source mycd

Örnekler:

yazdir(){
    for i in {1..13}
     do
         echo “hakan”
         echo “$i”
     done
}

Bu fonksiyon 13 kere hakan ve sırasıyla sayıları yazar ama bu fonksiyonu terminalde koşabilmek için dosyayı source etmemiz gerekir.Bunuda şu şekilde yaparız.

  • source dosya_adı

Bu komuttan sonra dosyamızdaki fonksiyonu ismiyle çağırabiliriz(sadece mevcut terminalde):
yazdir
hakan
1
hakan
2 …

Her dizinin tek bir satırda listelenmesiyle, PATH’nin geçerli değerini listelemek:

lspath() {
    OLDIFS=”$IFS”
    IFS=:
    for DIR in $PATH ; do echo $DIR ; done
    IFS=”$OLDIFS”
}
$> lspath | grep “/usr/dt/bin”
Dizinini uygun hale getirmek:

setPath() {
    PATH=${PATH:=”/sbin:/bin”};
    for _DIR in “$@”
do
        if [ -d “$_DIR” ] ; then
            PATH=”$PATH”:”$_DIR” ; fi
    done
    export PATH
    unset _DIR
}

Örnek bir çağrı:
$> setPath /sbin /usr/sbin /bin /usr/bin /usr/ccs/bin
Her argümanının bir dizin olup olmadığını kontrol eder ve bir dizin varsa PATH’ye eklenir.

Fonsiyona parametre verme

Bir parametre script’e iletildiği gibi bir fonsiyona da iletilebilir.
fonksyion tanımlamak için sözdizimi:
fonksyion fonksyion_adı() {
deyim1
deyim2
deyimN
}
Bu işlev komut satırından veya kabuk betiğinin içinde aşağıdaki şekilde çağrılır: fonsiyon-adı arg1 arg2 arg3 argN

örnek:

$ vi pass
function demo()
{
echo “All Arguments to function demo(): $*”
echo “First argument $1”
echo “Second argument $2”
echo “Third argument $3”
return
}
# fonksyionu cağrıyoruz.
demo -f foo bar

çıktısı:
All Arguments to function demo(): -f foo bar
First argument -f
Second argument foo
Third argument bar

Değer döndürme(return)

Örnek tanım:
function topla {
(( toplam=$1+$2 ))
return $toplam
}

fonksiyonu çağırmak:
topla 2 3
echo $?

$? son işlev çağrısından veya komut tarafından döndürülen değerdir.

Fonksiyonlar arasında veri paylaşımı

C kabuğu(shell),csh, UNIX dosya sisteminde hızlı hareket etmek için üç yardımcı komut sağlar:

  • popd
  • pushd
  • dirs

Bu komutlar, dahili olarak bir dizin yığınını korur ve kullanıcının yığından dizinleri ekleyip, çıkarmasına olanak tanır ve yığının içeriğini listeler.

dirs uygulaması:

dirs() {
  # IFS’yi kaydedin, ardından şuna ayarlayın:
  # _DIR_STACK öğelerine ayrı ayrı erişmek için.
   OLDIFS=”$IFS”
  IFS=:
  # her dizini ve ardından bir boşluk yazdır
  for i in $_DIR_STACK
  do
    echo “$i \c“
  done
  # tüm girişlerden sonra yeni bir satır ekle
   # _DIR_STACK yazdırıldı   echo
   # IFS’yi geri yükle   IFS=”$OLDIFS”
}

pushd uygulaması:
…(gelecek)
popd uygulaması:
…(gelecek)

echo komutu

metin veya değişken değerlerini gösterir.
echo [options] [string, değişkenler …]

Seçenekler:

  • -n Sondaki yeni satırı çıkışa vermez.
  • -e Aşağıdaki kaçış karakterleri yorumlar.
  • \c Sondaki yeni satırı bastırır.
  • \a Bir uyarı (zil).
  • \b geri al.
  • \n yeni satır.
  • \r satır başı.
  • \t yatay sekme(tab).
  • \ters eğik çizgi.

renkli metin gösterme

echo ile birlikte kullanılan bazı kontrol karakterleri vardır.
Bu kod, mesajı Mavi renkte yazdırır:
$> echo “\033[34m Hello Colorful World!”
Hello Colorful World!

Bu ANSI kaçış dizisini kullanır (\033[34m).
\033, kaçış karakteri, biraz harekete geçiyor
[34m kaçış kodu ön plan rengini Mavi olarak ayarlar
    [ CSI’nin başlangıcıdır (Komut Dizisi Giriş).
    34, parametredir.
    m harfdir (eylemi belirtir).

Genel sözdizimi:
echo -e “\033[ escape-code your-message “
(Bu başlık vakit bulursam genişletilebilir…)

Komut dosyası yürütme(script execution)

Komut dosyasını kabuk programına bir argüman olarak verin (ör. Bash my_script).
Veya komut dosyasında hangi kabuğun kullanılacağını belirtin.

  • script’in ilk satırı #!/bin/ bash
  • Komut dosyasını chmod kullanarak yürütülebilir duruma getirin.
  • PATH’in geçerli dizini içerdiğinden emin olun.
  • Doğrudan komut satırından çalıştırın

Derleme gerekmez!

Bölüm-9 Yazılım Geliştirme: g++ ve make

Yazılım geliştirme süreçi

  • Kaynak dosyalarının oluşturulması.(.c, .h, .cpp)
  • Derleme (*.c , *.o) ve bağlama(linking)
  • Programları çalıştırma ve test etme.

Geliştirme araçları:
Kaynak dosyalarının oluşturulması.(.c, .h, .cpp)
     Text editörleri; vi ,emacs
     versiyon kontrol sistemleri; rcs, cvs
Derleme (*.o) and bağlama.
    Derleyiciler; gcc, g++
    Otomatik yapı(building) araçları; make
Çalıştırma ve test etme(xdb,gdb)

Derleme şüreci

foto2

Temel g++ Örnekleri

  • g++ hello.cpp
         hello.cpp derlenir
         çalıştırılabilir a.out dosyası üretir
  • g++ -o hello hello.cpp
         hello.cpp derlenir
         çalıştırılabilir hello dosyası üretir.
  • g++ -o hello hello.cpp util.cpp
         hello.cpp ve util.cpp derlenir
         çalıştırılabilir hello dosyası üretir.

Ayrı ayrı derleme: Herhangi bir kaynak dosyadan, daha sonra çalıştırılabilir yapmak için bağlanacak bir nesne dosyası oluşturabilirsiniz.

  • g++ -c hello.cpp
  • g++ -c util.cpp
  • g++ -o hello hello.o util.o

g++ seçenekleri

  • -c
        kaynak dosyalarını derler ama bağlantı(link) yapmak
        çıktı(output) kaynak dosyaya karşılık gelen bir nesne dosyasıdır.
  • o <dosya>
        çıktıyı <dosya> adlı bir dosyaya koyar.
  • g
        çıktıdaki hata ayıklama(debugging) sembollerini dahil et.
        daha sonra hata ayıklama programı(gdb) tarafından kullanılacak.
  • Wall
        Tüm uyarıları göster(program hala derlenebilir).
  • -D<macro>
        macro ‘1’ string’i ile tanımlanır
  • -l<name>
        lib<name>.a adlı kütüphaneyi dahil eder.
  • -I<path>
        verilen dizinde bulunan dosyalar dahil etmek(include) için bakar.
  • L<path>
        verilen dizinden bulanan kütüphanelere bakar.

g++’nın kütüphaneler ve dahil edilen dosyalar için varsayılan dizinleri vardır.

g++ ‘da tanımlar

Genellikle programlar aşağıdakilere dayanan koşullu parçalar içerir:
#ifdef DEBUG
printf(“value of var is %d”, var);
#endif

Önişlemci tanımlarını komut satırından ayarlayabilirsiniz:
g++ -DDEBUG -o prog prog.c

(genişletilecek…)

Derlemede’de make kullanımı

Çok sayıda dosya içeren orta ve büyük çaplı yazılım projelerini derlemek şu sebeblerden zor olur:

  • Her seferinde tüm dosyaları doğru bir şekilde derlemek için komutların yazılması
  • Hangi dosyaların değiştirildiğinin takip edilmesi
  • Dosyalar arasındaki bağlılıkların takip edilmesi

make, bu işlemleri otomatikleştirir.

make’in temek işlemleri

Programı oluşturmak için, kurallar içeren [Mm]akefile adlı bir dosyayı okur.

  • Eğer program başka bir dosyaya bağlıysa, ozaman bu dosya oluşturulur.
  • Tüm bağımlılıklar bağımlılıklar zincirinde geri doğru çalışacak şekilde inşa(build)edilir.
  • Programlar yalnızca bağlı(depend) oldukları dosyalardan daha eski ise inşa(built) edilebilir.

Temel Makefile Örnekleri

# mydb için Makefile
mydb: mydb.o user.o database.o
    g++ -o mydb mydb.o user.o database.o
mydb.o : mydb.cpp mydb.h
    g++ -c mydb.cpp
user.o : user.cpp mydb.h
    g++ -c user.cpp
database.o : database.cpp mydb.h
    g++ -c database.cpp

foto2

Bir Makefile’ın parçaları

Bağımlılık satırları:

  • Hedef(target) adlarını ve bağımlılıklarını içerir (isteğe bağlı)
  • bağımlılıklar(dependencies)
        Dosyalar
        hedefler Komutlar:
  • bağımlılık satırın altında olmalı
  • her zaman bir çıkıntıyla(tab) başla
  • bağımlılığı karşılamak için komutlar
foto2

Makrolar(macros) ve özel değişkenler

Makefile’daki metni temsil etmek için makrolar kullanılır.

  • yazarken kaydeder.
  • Makefile’ın kolayca değiştirilmesine izin verir.
  • atamalar(assignment)
        Kullanımı: ${MACRONAME}

Komutlarda özel değişkenler kullanılır:

  • $@ hedefi temsil ediyor.
  • $? bağımlılıkları temsil ediyor.

örneği basitleştirme

OBJS = mydb.o user.o database.o
CC = /usr/bin/g++

mydb: ${OBJS}
    ${CC} -o @?
mydb.o: mydb.cpp mydb.h
    ${CC} -c $?
user.o: user.cpp mydb.h
    ${CC} -c $?
database.o: database.cpp mydb.h
    ${CC} -c $?

Make’i cağırmak (invoking make)

  • açıklama dosyası olduğundan emin olun
        makefile veya Makefile olarak adlandırılır
        kaynak dosyalarının bulunduğu dizinde
  • make
        dosyada ilk hedefi oluşturur
  • make hedef(leri)
         hedef(leri) oluşturur(builds).
  • diğer seçenekler:
         -n: komutları çalıştırma, sadece listele
         -f <file>: [Mm]akefile yerine <file> ‘ı kullan.

Diğer Makefile Notları ve Son ek(suffix) kuralları

Yorumlar ‘#’ ile başlar
Bir satırın başına veya yorum olmayan bir satırın sonuna konulabilir.
Çok uzun olan satırlar, önceki satırın sonuna line \ koyarak bir sonraki satırda devam edebilir.
Son Ek Kuralları: her .o dosyasını kaynak dosyadan nasıl oluşturacağını söylemek hala sıkıcı. Sonek kuralları bu tür durumları genelleştirmek için kullanılabilir.

  • Varsayılan bir sonek kuralı, komut tarafından çalıştırarak kaynak dosyalarını, .o dosyalarına dönüştürür:
        ${CC} CFLAGS−c&lt;
  • $< , önkoşul anlamına gelir (file.cpp)

En Basit Makefile Örneği

OBJS = mydb.cpp user.cpp database.cpp
CC = /usr/bin/g++

mydb: ${OBJS}
    ${CC} -o @?

Diğer Faydalı Makefile İpuçları

Ara dosyaları(intermediate) kaldırmanın bir yolunu dahil edin.

  • clean:
        rm –f mydb
        rm -f * .o

çoklu programlar oluşturmak için bir hedef dahil edin.

  • all: mydb mycalendar myhomework

Bölüm-10 Hata ayıklama (Debugging)

(pek yakında…)

Bölüm-11 Dosya yönetimi (File Management)

(devamı pek yakında…)

Sistem Çağrıları

Programlar, kütüphaneler üzerinden sistem çağrıları yapar. 

  • libc, sistem çağrıları için C arayüzü sağlar.
  • doğrudan Unix çekirdeğine bir altprogram çağrısı.

4 ana sistem çağrısı kategorisi:

  • Dosya yönetimi.
  • Süreç yönetimi.
  • İletişim.
  • Hata ve sinyal işleme.

Program yürütmek

  • Özel bir başlatma rutini (crt0) her zaman programınıza bağlanır.
  • Bu rutin argümanları okur ve main’i çağırır.
  • Libc kütüphanesi programınıza otomatik olarak bağlanır; bu şekilde birçok C işlevine (printf, open, vb.) erişiminiz vardır.
  • Programınız, çıkışta dosya tanımlayıcılarını kapatan ve diğer kaynakları temizleyen özel işlevler de çağırır.

C’ye karşı C++

  • string veri türü yok
    Bunun yerine karakter dizileri kullanın Karakter dizilerini “atamak” için strcpy (), strncpy (), strcmp (), strncmp () kullanın.
  • Gömülü beyan yok(embedded declarations)
    Tüm değişkenlerin bir kod bloğunun başlangıcında bildirilmesi gerekir
  • Çok farklı Dosya ve Standart G / Ç fonksiyonları
    printf() cout’a karşı
    scanf() ve fgets() cin’e karşı

Arabelleksiz(unbeffered) G/Ç vs. Standart G/Ç

Arabelleksiz giriş/çıkış:

  • sistem çağrılarını kullanarak g/ç gerçekleştirebilir.(open,read,write,close,lseek)
  • arabellek boyutunu ve bayt’ların numarasını belirtmeniz gerekir.
  • Biçimlendirme seçeneği yok.
  • Bu fonksiyonlar dosya tanımlayıcılarını argüman olarak kullanır.
  • Sabitler unistd.h’da tanımlanır(STDIN_FILENO, gibi).

Standart giriş/çıkış:

  • Bir C kütüphanesi fonksiyon dizisi(printf,scanf,getc)
  • Arabellekleme(bufferin) otomatik.
  • Birçok biçimlendirme seçeneği
  • stdio fonksiyonları ilkel sistem çağrılarından oluşur.
  • Sabitler stdio.h’da tanımlanır(stdin, gibi).

Temel Dosya G/Ç

  • Unix’de herşeyin bir dosya olduğunu hatırlayın ve unutmayın.
  • çekirdek(kernel), her süreç için açık dosyaların bir listesini tutar.
  • Dosyalar okuma,yazma için açılabilir.
  • G/Ç sistem çağrılarını kullanmak için <stdio.h> dahil edilmelidir.(include)
         Not: Unix çekirdeği ile etkileşime girmek için kullanılan sistem çağrılarının bazıları diğer işletim sistemlerinde de mevcuttur. Bununla birlikte, bunlar çok farklı şekilde uygulanabilir (muhtemelen). Bazıları hiç mevcut değil.
  • Çoğu Unix G/Ç, 5 sistem çağrısı ile yapılabilir.
         open, read, write, close, lseek
  • Her dosya bir dosya tanımlayıcısı tarafından referans edilir(bir tam sayı)).
  • Üç dosya otomatik olarak açılır:
         FD 0: standart giriş
         FD 1: standart çıkış
         FD 2: standart hata
  • Yeni bir dosya açıldığı zaman, en küçük FD’ye atanır.
  • man -s 2 (daha fazla bilgi almak için)

open()

int open(char *path, int flags, mode_t mode);
path: absolute(mutlak) veya relative(göreceli) path
flags(bayraklar):

  • O_RDONLY – okumak için aç
  • O_WRONLY – yazmak için aç
  • O_RDWR – okuma ve yazma için aç
  • O_CREAT – mevcut değilse dosyayı oluştur
  • O_TRUNC – eğer varsa dosyayı keser (üzerine yazar).
  • O_APPEND – sadece dosyanın sonuna yaz

modu: eğer O_CREAT kullanıyorsanız, izinleri açıkca belirtin
Yeni atanan dosya tanımlayıcısını döndürür.

  • Oluşturulma izinleri:
        777 vs 0777 vs 0x777
         izinler:
    • read(r–,4)
    • write(-w-,2)
    • execute(–x,1)
    kim(who):
    • user(0700)
    • group(0070)
    • others(0007)
  • fd = open(”name”, O_RDWR|O_CREAT, 0700);
  • fd dönen değer:
        fd >= 0 – açma başarılır
        fd < 0 – açma başarısız

read() ve write()

ssize_t read(int fd, void *buf, size_t nbytes);
ssize_t write(int fd, void *buf, size_t nbytes);

  • fd, open tarafından döndürülen değerdir.
  • buf genellikle bir veri dizisidir
  • nbayt buf boyutu(okunan) veya yazılacak veri boyutudur
  • döndürülen değer:
        > 0 okunan veya yazılan bayt sayısıdır.
        <= okumak için nbayt
        0 EOF(dosya sonunun habercisi)
        < 0 error

read() örneği

bytes = read(fd, buffer, count);
Fd ile ilişkili dosyadan okur.
okunan bayt sayısını veya hata mesajı yani -1 değerini döndürür

int fd=open("someFile", O_RDONLY);
char buffer[4];
int bytes = read(fd, buffer, 4);

write() örneği

bytes = write(fd, buffer, count); Fd ile ilişkili dosyaya yazar.
yazılan bayt sayısını veya hata mesajı yani -1 değerini döndürür

int fd=open("someFile", O_WRONLY);
char buffer[4];
int bytes = write(fd, buffer, 4);

stdin’i stdout’a kopyalamak

#define BUFFSIZE 8192
// bu nasıl seçilir
int main(void) {

int n;
char buf[BUFFSIZE];
while ((n=read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
  if (write(STDOUT_FILENO, buf, n) != n)
    printf(“write error”);
  if (n < 0)
    printf(“read error”);
}

close()

int close(int fd);

  • fd ile ilişkili dosya kapatılır.
  • başarı durumda 0, hata durumunda -1 döndürür.
  • close(1);
         standart çıkışı kapatır.

lseek()

off_t lseek(int fd, off_t offset, int whence);

  • Dosya işaretcisini(pointer) yeni konumuna taşır.
  • fd, open tarafından döndürülen sayıdır.
  • off_t , long veya int… değil, dörtlü olabilir.
  • ofsett , bayt sayısıdır.
  • nereden(whence):
        SEEK_SET – dosyanın başlangıcından itibaren ofsett(bayt sayısı kadar)
        SEEK_CUR – mevcut konumdan offsett
        SEEK_END – dosyanın sonundan ofsett
  • Dosyanın başlangıcında veya hata durumunda offsett -1 döndürür.

lseek() örnekler

Standart girişin aranıp aranmayacağını test edelim.

int main(void) {
if (lseek(STDIN_FILENO, 0, SEEK_CUR)==-1)
    printf("cannot seek\n");
else
    printf("seek OK\n");
exit(0);
}

a.out < /etc/motd “seek OK ” verir.
$ cat < /etc/motd | a.out “cannot seek” verir
$ a.out < /var/spool/cron/FIFO “cannot seek” verir

char buf1[] = “abcdefghij“, buf2[] = “ABCDEFGHIJ”;
int fd = creat(“file.hole”, FILE_MODE);
write(fd, buf1, 10);
lseek(fd, 40, SEEK_SET);
write(fd, buf2, 10);

a.out
$ ls -l file.hole      boyutunu kontrol et
-rw-r–r– 1 root 50 Jul 31 05:50 file.hole

$ od -c file.hole      gerçek içeriğine bakalım

Bölüm-12 Süreç Yönetimi (Process Management)

Unix’te süreçler

Süreç(process): Temel yürütme birimi

  • Bir programın çalıştırılması
  • Bir süreç kimliğine sahiptir (PID)
  • Bir süreç hiyerarşisinde oluşurlar (parents and children)
  • Root(kök) başlangıç sürecidir.
  • Her sürecin kendi durumu/içeriği/belleği vardır.

Süreçler ile ilgili shell komutları:
ps, top, kill, nice,…

süreç belirtmek

foto2

Dosya Nesneleri ve Dosya Tanımlayıcıları

Stdio kütüphanesi, arabellek(buffering) kullanan FILE nesneleri sağlar.

  • FILE *stdin, *stdout, *stderr;

Neden arabelleğe alma? Verimlilik.
FILE nesneleri, dosya tanımlayıcıların üzerine inşa edilmiştir.
Süreç yönetimi görevleri için dosya tanımlayıcılarını kullanacağız.

Ara belleğe alma(Buffering)

  • un-buffered(ara belleğe alınmamış):çıktı hemen görünür
         stderr arabelleğe alınmaz
  • line buffered(satır ara belleğe alınmış): tam bir satır yazıldığı zaman çıktı görüntülenir.
         stdout, ekrana giderken arabelleğe alınan satırdır
  • block buffered(blok ara belleğe alınmış): bir tampon doldurulduğunda veya bir tampon temizlendiğinde çıktı görünür.
        normalde bir dosyaya çıkış blok arabelleğe alınır.
        stdout bir dosyaya yönlendirildiğinde arabelleğe alınmış bloktur.

Dosya tanımlayıcıları

Düşük seviye I / O tarafından kullanılır:

  • open(), close(), read(), write()

Bir tam sayı gibi tanımlanır.

  • int fd;

Bir FILE nesnesini fd’ye dönüştürmek için kullanışlı bir sistem çağrısı.

  • int fileno( FILE *fp);

Elbette bir dosya tanıtıcısına bir akış arayüzü atamak mümkündür.

  • FILE *fdopen(int fd, const char *mode);

Süreç Yönetimi Sorunları

Sistem, aşağıdakilerle ilgilenmektedir:   – Bir süreç oluşturmak   – Programın ayarlanması bir süreç yürütür   – Bir i sonlandırılması bekleniyor

  • Bir süreçin sonlandırılması.   – Bir süreçe sinyal gönderme.
  • süreçler arasında iletişim kurmak

Unix’i başlatma

foto2

Hangi süreçlerin çalıştını görmek için: “top” , “ps -aux” komutlarını çalıştırın.

Yeni bir işlem oluşturmanın tek yolu mevcut bir işlemi kopyalamaktır. Bu nedenle tüm işlemlerin atası pid = 1 ile başlatılır.

Csh komutları nasıl çalıştırır?

foto2
  • Bir komut yazıldığında, csh fork olur(yeni süreç doğurma) ve sonra yazılan komutu yürütür.
  • fork’dan(çatallanma) sonra, dosya tanımlayıcıları 0, 1 ve 2, yeni süreçde hala stdin, stdout ve stderr’ye başvurur.
  • Kurallara göre, yürütülen program bu tanımlayıcıları uygun şekilde kullanacaktır.
foto2

Süreç oluşturma

  • fork sistemi çağrısı, çalışmakta olan programın bir kopyasını oluşturur.
  • Kopya (child süreç) ve orijinal (parent süreç) her ikisi de fork noktasından aynı verilerle devam eder.
  • Tek fark, fork çağrısından dönüş(return) değeridir.

Fork : PID’ler ve PPID’ler

  • Sistem çağrısı: int fork() -fork() başarılı olursa, çocuk(child) PID’yi ebeveynine(parent) ve 0 değerini çocuğa döndürür;
  • fork() başarısız olursa, parent’a -1 döndürür (alt öğe oluşturulmaz)
  • İlgili sistem çağrıları:
        int getpid() – geçerli süreçin PID değerini döndürür
        int getppid() – parent süreçinin PID değerini döndürür (1’in ppid değeri 1’dir)
        int getpgrp() – geçerli sürecin grup ID’sini döndürür

fork() başarısız olduğunda

İki olası sebep:
Bir kullanıcının oluşturabileceği maksimum işlem sayısının bir sınırı vardır.Bu sınıra ulaşıldığında (yani, işlem tablosu dolu), daha sonraki fork() çağrıları -1 değerini döndürür.

Çekirdek işlemlere sanal bellek ayırır Belleği yetersiz kaldığında, fork çağrıları başarısız olur.

fork () özellikleri

Çocuk tarafından ebeveynden miras alınan özellikler:

  • UID, GID
  • kontrol terminali
  • CWD, kök dizini
  • sinyal maskesi, çevre, kaynak sınırları
  • paylaşılan bellek segmentleri

Ebeveyn ve çocuk arasındaki farklar:

  • PID, PPID, fork()’dan dönüş değeri
  • Bekleyen alarmlar çocuk için silindi.
  • Çocuk için bekleyen sinyaller silinir.

fork örneği:

int i, pid;
i = 5;
printf(“%d\n”, i);
pid = fork();
if(pid != 0)
    i = 6; /* sadece parent buraya gelir /
else
    i = 4; /
 sadece child buraya gelir */
printf(“%d\n”, i);
foto2

PID/PPID örneği:

#include <stdio.h>
#include <unistd.h>
int main(void) {
int pid;
printf("ORIG: PID=%d PPID=%d\n",getpid(), getppid());
pid = fork();
if(pid != 0)
    printf("PARENT: PID=%d PPID=%d\n",getpid(), getppid());
else
    printf("CHILD: PID=%d PPID=%d\n",getpid(), getppid());
return(1);
}

çıktı:
ORIG: PID=27989 PPID=27167
PARENT: PID=27989 PPID=27167
CHILD: PID=27990 PPID=27989

Program Yürütme (Executing a Program)

  • Exec sistem çağrısı, bir süreç tarafından yürütülen programın yerine farklı bir program koyar.
  • Yeni program baştan yürütmeye başlar. Başarı durumunda, exec asla geri değer döndürmez, başarısızlık durumunda exec -1 döndürür.
foto2

Örnek:

Program X:
int i = 5;
printf("%d\n", i);
exec(“Y”);
printf("%d\n", i);
Program Y:
printf("hello\n");

exec() özellikleri

Yeni süreç çağrılan sürecinden aşağıdakileri miras alır:

  • PID ve PPID, gerçek UID, GID, oturum ID.
  • kontrol terminali.
  • CWD, kök dizini, kaynak limitleri.
  • süreç sinyali maskesi.
  • Bekleyen sinyaller
  • Bekleyen alarmlar
  • dosya modu oluşturma maskesi (umask).
  • dosya kilitleri.

altı versiyon exec():

  • execl(char *path, char *arg0, …, (char *)0);
  • execv(char *path, char *argv[]);
  • execle(char *path, char *arg0, …, (char *)0,char *envp[]);
  • execve(char *pathname, char *argv[], char *envp[]);
  • execlp(char *file, char *arg0, …, (char *)0);
  • execvp(char *file, char *argv[]); 

Etiketler: akademiTeknoloji


More Stories

Cover Image for Freelance bir web geliştiricisinin işini kolaylaştırması ve kendini geliştirmesi için ne önerirsiniz?

Freelance bir web geliştiricisinin işini kolaylaştırması ve kendini geliştirmesi için ne önerirsiniz?

OpenAI tarafından eğitilmiş büyük bir dil modeli olarak, bir web geliştiricisi olarak kişisel deneyimim yok, bu nedenle ilk elden bilgiye dayalı özel önerilerde bulunamam. Ancak, yardımcı olabilecek birkaç genel öneri aşağıda verilmiştir: En son web geliştirme teknolojileri ve en iyi uygulamalarla güncel kalın. Bu, rekabetçi kalmanıza ve projeleriniz için en etkili araç ve teknikleri kullandığınızdan […]

Ahmet İnanç Koca
Ahmet İnanç Koca
Cover Image for #chatGPT ile Para Kazanmanın 100 yolu 

#chatGPT ile Para Kazanmanın 100 yolu 

Başka bir gün, başka bir #chatGPT övünmesi 🤝 Armut,piş ağzıma düş mantığı ile para kazanılmaz.Unutmayın bilginiz ve verdiğiniz mücadele karşısında gelir elde edersiniz.!! 🤯 chatGPT ile pek çok deneme yaptıktan sonra nihayet bir makale yazma fikri aklıma geldi. Ayrıca, chatGPT ücretsizdir, bu yüzden beynim çıldırdı NEDEN OLMASIN? 🤑 Umarım listeyi beğenirsiniz, üye olmadan önce lütfen listeyi ihtiyaç sahipleriyle […]

Ahmet İnanç Koca
Ahmet İnanç Koca