You are on page 1of 25

ders notları

/******
Açıklama: Bu notları derse çalışırken kendim için yazmıştım, bu sebeple
notlarda eksik ve hatalı kısımların olma ihtimali çok yüksek. FD.

******/

exec 4 < fileName → fileName dosyasına 4 fd’si


verildi. bu dosyayı stdin olarak kullanabiliriz
cat <&4 → fileName’de yazanı ekrana gösterir

exec 5> fileName → fileName dosyası oluşturdu, fd’sini


5 yaptı
echo “walter” >&5 → 5 fd’li dosyayı stdout olarak
kullandı
6 >&5 → 6 fd’si 5’in olduğu kaynağa bağlandı

someCommand 1>fileName → 1 unixte stdout’u temsil


ettiği için 1 yazmasan da olur
someCommand 0<fileName → 0 yazmasan da olur

someCommand >>fileName 2>fileB → stdout çıkışları


fileName’in sonuna yapılır, stderr ise fileB’ye

someCommand >fileName 2>&2 → 1 fileName’e bağlandı, 2


ise fileName’in bağlandığına bağlandı. sonuç olarak
hem out hem err aynı yere yazılacak

ders notları 1
echo $PWD >> fileName → dosyanın sonuna pwd bilgisini
ekler

command1 | command2 → command1 write(1..), command2


read(0,..) durumunda olmalı yani biri stdouta yazmalı,
diğeri stdinden okumalı
ls * | wc → ilki tüm içerikleri yazar, wc(word count)
bu yazılanı giriş olarak alır ve satır sayısı,
karakter sayısı gibi bilgileri ekrana yazar

command1 ; command2 → önce ilk komut çalışır, o


bitince ikinci komut
echo “lalo salamanca” ; sleep 5 ; date ; ls -al → lalo
yazar, 5 saniye bekler, tarihi yazar, ls bilgisini
yazar
command1 & command2 → aynı anda çalıştırma. k için
command1 & command2 & → shell komutların yapılmasını
beklemeden yeni bir komut satırı verir

ls -al | head → dosyanın ilk 10 satırı


head -3 → böyle yaparsan okuyacağı bir veri olmadığı
için konsoldan üç satır okur
ls -al | tail → son 10 satır. -5 dersen son beş satır.
+ dersen beşinci satırdan sonrası

cmp file1 file2 → iki dosyanın içeriğini kıyaslar,


farklı olan ilk satırı return eder
diff file1 file2 → farklı olan tüm satırları return
eder
od file1 → dosyanın içeriğini oktal tabanda gösterir
od -c file1 → newline karakterleri \n olarak gösterir

ders notları 2
ls -lt → zamana göre sıralar

uniq -d → arka arkaya tekrarlanan satır varsa o


satırların ilkini gösterir
uniq -u → tekrarlanmayan satırlar

egrep “abd” fileName → abd içeren satırlar. tırnak


koymazsan eğer pattern yerine yazdığın şey shell
tarafından yorumlanabilir bir şeyse önce yorumlama
yapılır

egrep abd* fileName → dizin içerisinde abd ile


başlayan tüm dosyaları bulur ve isimlerini abd* yerine
yazar. ardından fileName içerisinde bu pattern aranır

egrep -i “abd” fileName → büyük küçük fark etmez. -v →


abd’yi içermeyen. -n → dosyanın kaçıncı satırı
olduğunu söyler. -c → abd’yi kaç satır içeriyor

egrep “abc|def” fileName → abc ya da def arar

egrep “f\*” fileName → * karakterini normal karakter


olarak kullanmak için
egrep “^[^e]*e[^e]*$” → içinde yalnızca bir tane e
içeren. başlangıçta e hariç bir karakterden herhangi
sayıda, sonrasında 1 adet e, sonunda da e hariç
karakterden

ders notları 3
herhangi bir sayıda. []
ifadesinde ilk karakter ^ ise bu karakterler hariç
demektir
egrep “^[^abc].*” fileName —> a b ya da c ile
başlamayan
egrep “[fF]un” fileName → fun, Fun. [A-Z]
egrep “a(bc)*” fileName → parantezler gruplama için
kullanılır. a, abc, abcbc, abcbcbc
egrep “[a-z]{3]” fileName → karakterler kendini üç kez
tekrarlayabilir
egrep “m.{2, 4}” fileName → en az iki en az dört kez

egrep -f myPatt fileName path → patterni myPatt


içerisinde tanımladık, oradan alacağız
alias e=echo → yazması zor komutlara yeni isim vermek

→ C/C++ benzeri bir yazı yazmak için çift parantez


yapısı kullanılır
var=10
i=$((var++))
i=$((var2=var++)) → var: 10, var2: 9, i: 9. echo $i
diyerek değerlerine bakılabilir
echo $((var2*7))

a=104946

var1=”$var2 $var3” → string birleştirme

$varName
${varName} → değişkenin değerine bakma
${varName:—value} → değişkenin değeri

ders notları 4
setlenmemişse value değerini kullan
$varName:=value} → değişkenin değeri
setlenmemişse değişkenin değerini value yap
${varName:?value} → değişkenin değeri
setlenmemişse strerr’e value yazar
${varName:+value} → setlenmişse value değerini
kullan, setlenmemişse null kullan

echo {varName?pattern} → pattern olarak egrep değil


shell meta karakterleri kullanılır. sondan başlayarak
patterne uyan ilk kısmı siler
echo {varName??pattern} → maximum eşleme yapar. ilki
minimum eşleme yapar. burada maximum eşleme bütün
halinde yani ortada bir yerin eşlenmesinden
bahsetmiyoruz
echo {varName#pattern} → baştan eşleme

→ arraylerde boyut bildirimi yapılmaz


${a[3]} → a dizisinin elemanına erişmek için
${a} → ilk elemana alternatif erişim
a[2]=20 → eleman ekleme
b=($a 30) → listenin birinci elemanını alır, bu
eleman ve 30 içeren yeni bir array oluşturur
b=(${a[@]} 30) → a’nın tüm elemanlarını alır, 30
ekler ve yeni bir array olarak return eder
b=(${a[*]} 30) → üsttekinin alternatifi. a[*] ve a[@]
tüm listeyi ifade eder
b=${#a[*]} → nulldan farklı olan elemanlar için
dizi boyutu
→ ileri bir indexe değer atarsan arada kalanların
değeri null olur

ders notları 5
b=(*) → çalışma dizinindeki tüm dosyalardan
array yapar. eğer shell eşleşme bulamazsa array *’dan
ibaret olur

y=11
x=20
> myFile → myFile bir script dosyası, onu
çalıştırıyoruz. dosya x ve y değerlerini ekrana
yazdırıyor ama dosyanın bu değerlere erişimi yoktur
y=
x= → ekrana yazılacak olan şey
export x y → değişkenleri export ettik
> myFile
y = 11
x = 20

> ( cd ../bin ; ls) → parantez bir child process


oluşturulur ve içerideki işlem bu subshell içerisinde
yapılır. burada ls bin dosyasının içeriği yazar
> ls → üstteki komut child processte
olduğu için konum değişikliği parentı etkilemez. pwd
içeriği yazılır
> { cd ../bin ; ls} → parent shell kodu yorumlar
> (ls; pwd; date;) | wc → parantez yapısı subshellerin
sonuçlarını birleştirir. bu veri pipe’a yönlendirilir,
wc bu verinin tamamı üzerinde çalışır
> x=50; (x=100); echo $x → 50 print eder

> export x=10


> (echo $x; x=20; echo $x;); echo $x → 10 20 10 print
edilir

ders notları 6
echo “my age is $x” → bir değişkeni çift tırnaklı
yerde kullanmak için
echo “date is `date`" -> bir komutu çift tırnak
içerisinde kullanmak için
echo "date is $(date)" -> alternatif

→ örneğin bir script dosyası 7 return ediyorsa,


dosyayı çalıştırdıktan sonra echo $? değeri 7 olur.
bir kez daha echo $? yaparsak 0 olur çünkü bu değer
çalışan son
komuta göre değer alır

name=”saul” → boşluk bulunan atamada tırnak


kullanılmalı

read varName → whitespace’e göre girişleri varName’e


atar → baştaki ve sondaki boşluklar atılır
read var1 var2 → ilk sözcük var1’e, kalanı var2’ye

expr 2+5 → ((2+5)) gibi çalışır

> scriptName b c d → scripte komut satırı argümanı


verdik
$* b c d stringi, $@ b c d içeren argüman arrayini
belirtir

cp file1 file2 // file1 içeriği file2’ye kopyalanır,


file2 yoksa oluşturulur
mkdir dirName // dir oluşturur

cat file1 > file2 // file1 içeriği file2’ye


yazılır

ders notları 7
cat < file1 // file1 içeriğini ekrana
yazar
exec 3<file1; cat &3>file2 // 3 nolu fd’yi file1’a
atadık, ardından 3 nolu fd içeriğini file2’ye aktardık
ls -al >file1 // ls-al’yi file1’e yazar
ls >/dev/fd/1 // ls bilgisini 1 nolu
fd’nin bağlı olduğu kaynağa yazar. /dev/fd/ dizini
sistemdeki fd’lerin tutulduğu yerdir. dizin olduğu
için openla
// kullanılabilir
ls >>/dev/fd/8 // 8 nolu kaynağa append
yaparak yazar.

more fileName // dosyanın içeriği


cat fileName // dosyanın içeriği
cat fileName fileName2 // birden çok argüman
verilebilir
read varName // veri okur ve varName’e
yazar
man ls // ls komutunun açıklamasını
yazar
tail +1 fileName // dosyanın 1. satırından
itibaren geri kalan kısımları yazdırır(1. satır dahil)
tail -2 // dosyanın son iki satırını
yazdırır
sort file1 // alfabetik olarak sıralar.
ilk karakterler rakam ise rakamlara bakarak düzgün
olmayan bir sıralama yapar
sort -r file1 // üsttekinin tam tersi
olarak çalışır
sort -n file1 // rakamlara göre düzgün

ders notları 8
sıralar, alfabetik de düzgün sıralar
cut -c2 file1 // her satırın ikinci
karakteri
cut -c2,3 file1 // her satırın 2. ve 3.
karakteri
cut -c2-6 file1 // her satırın 2. 6. arası
karakterleri. 6. karakter dahil değil
cut -d “ “ -f1 // her satırı boşluğa göre
parçalar, ilk parçayı alır
cut -d a -f2 // a karakterine göre
parçalar, ikinci parçayı alır
wc fileName // satır kelime karakter
bilgisi. wc -l → satır, wc -w → kelime, wc -c →
karakter
head -100 // ilk 100 satır
uniq -c // hangi satırın arka arkaya
kaç defa tekrarlandığını yazar
ps // çalışan processleri
listeler

echo -n “x” // bir sonraki satıra


inilmeden print yapılır

(( condition )) // sayısal ifadeler için koşul


ikili parantez içine yazılır
(( i < 10 ))
[ [ condition ] ] // string ifadeleri için koşul

$(a) // a bir komut olarak göz önüne alınır

ders notları 9
a=(10 20) // dizi oluşturma
${a[@]} // tüm diziyi belirtir

${#a} // string uzunluğu


${a:5:1} // beşinci indexten itibaren bir
karakter
${a:4} // 4. indexten itibaren

ls > a // a dosya ismi olmalıdır


a=a // soldaki a değişken, sağdaki a değer ya da
elemandır. a değişkenine a değeri atanır.

$((a)) // a bir değişken olarak görülür. a nın


değeri burada kullanılır
$(($a)) // üsttekinin aynısı
(a) // dizi olarak görülür
a=(a) // a dizisi, ilk elemanı a
a=($a) // a dizisi, ilk elemanı a’nın değeri

a=3 // a bir yerel değişken


echo $a // a’nın değerini öğrenme
a=3; echo $a // tek satırda

${n} // komut satırı argümanı sayısı 9’dan fazla


ise bu notasyon kullanılır

egrep pattern fileName // genel syntax. egrep verilen


pattern ile eşleşen dosya satırlarını gösterir
egrep “a.b” fileName // bir karakter eşler. acb,
a1b, a3c
egrep “a..b” fileName // iki karakter eşler

ders notları 10
egrep “ab*c” fileName // sıfır ya da daha fazla
anlamına gelir. ac, abc, abbc, abbbc.
egrep “.*” fileName // tüm stringler
egrep “^D.*” fileName // D ile başlayan satırları
arar. ^ satır başını gösterir
egrep “.*D$” fileName // D ile biten satırlar. sonda
bulunan $ satır sonunu gösterir
egrep “ab+c” fileName // karakter kendini bir ya da
daha fazla kez tekrarlar. abc, abbc, abbbc.
egrep “ab?c” fileName // karakerin sıfır ya da bir
kez tekrarlanması. ac, abc

> scriptName b c d // scripti üç argüman ile


çalıştırdık
$# // argüman sayısı
$1 // ilk argüman
$2 // ikinci argüman
shift // komut satırının ilk
argümanını siler, geriye diğerleri kalır. argümanlarla
tek tek işlem yaparken kullanılan bir ifadedir
$0 // scriptin kendisi. scripti
recursive olarak yeniden çağırırken kullanılır
$0$* // scripti aynı argümanlarla
recursive olarak tekrar çağırmak

[ [ -e fileName ] ]; echo $? // fileName dosyası


bulunuyor mu, $? bir önceki işlemin çıkış durumunu
verir. eğer dosya varsa 0 yazdırılır
[[ -d $2 ]] // directory mi?

(( 100 == 200 ))
echo $? // 1 sonucunu verir

ders notları 11
pwdd
echo $? // 1 sonucunu verir
çünkü böyle bir komut yok

test 10 -eq 20
echo $? // 1 return eder

a=`date` // date komutunun sonucunu a’ya


atar
a=`ls`
echo $a
b=$(ls) // ters tırnağın alternatifi

// eval komutu iki kere değerlendirilir, text şeklinde


komut satırından shell komutu girersek eval kullanarak
bu komutları çalıştırabiliriz
pipe=”|”
ls $pipe wc // hata verir, | ve wc’yi ls’in
argümanı zanneder

pipe=”|”
eval ls $pipe wc // ls | wc olarak görür

// örnek kod
eval echo \$$# // argüman yoksa ilk geçişse $0
olarak görür
// ikinci geçişte ise scriptin
ismini yazar

// üstteki scripti * argümanı ile çağırırsak


eval echo \$$# // geçişlerden shell * yerine

ders notları 12
dizindeki dosyaları ekler. dizinde 49 tane dosya
olduğunu düşünelim
// ilk geçişte $49.
// ikinci geçişse 4. komutu
satırı argümanı9 şeklinde bir çıktı üretir

basename /usr/bin/myscript
$> myscript // dizinden dosyanın ismini
türetir

date | tee now // tee komutu çoğunlukla pipe


kullanılan bileşik işlemlerde pipe’e yazılan veriyi
bir dosyaya yazmak
// ve kendinden sonraki pipe’a
vermek için kullanılır. burada date bilgisini now
isimli bir dosyaya yazar
ls | tee list | wc // ls bilgisini pipe’dan alır ve
list’e yazar, aynı veriyi sağdaki pipe’a aktarır
tee zzz // tek başına kullanılırsa
stdin’den alır, stdout’a ve zzz’ye yazar
// dosya ismi mevcutsa içeriğini
siler

// PATH shell değişkenindeki : ayıracına göre print


yapacak fonksiyon
lsPath(){
oldifs=”$IFS” // $IFS shellin parçalama yaptığı
sistem değişkenidir. değeri boşluktur
IFS=: // IFS değerini iki nokta yaptık
for DIR in $PATH
do
echo $DIR // bütün sistem yollarını düzgün

ders notları 13
şekilde print eder
done
}
lsPath // fonksiyonun çağrılışı

// toplama yapan bir fonksiyon ve onun farklı


şekillerde çağrılışı
function add_to(){
(( sum=$1+$2 ))
echo $sum
# return $sum
}

add_two $1 $2
echo $?
a=$(add_two 2 3)
echo $a
// script sonu
> add_two 3 4 // scripte(scriptin adı da add_two)
iki argüman geçtik
// bu argümanlar bodyden sonraki ilk
satırda fonksiyonu çağırmakta kullanıldı
// 7 yazıldı. işlem başarılı oldugu
için $? de 0 yazdı. ardından fonksiyon
// 2 3 ile çağrıldı. 5 değeri ekrana
yazılacaktı ama $()’dan dolayı çıkış a’ya
yönlendirildi
// eğer return satırını yorumdan çıkarırsak $?’a
return değeri yerleşecektir
// fonksiyon içerisinde $1 ilk parametre, $* tüm
parametreler anlamına gelir

ders notları 14
// not: return edilen değer sayısal ise $? ve a=$()’e
geçer, ama string return ediliyorsa $?’ya geçmez.

echo -e “vj\tbülent” // escape karakterleri


değerlendirerek print eder. vj bülent

sistem çağrıları

int main(){

int fd, n;
char buf[10]
printf(”%d”, BUFSIZ) // sistemin buffer
boyutunu tutan global bir değişken
write(2, “bufsize1: “, 10) // 2’nolu fdye yani
stderr’e 10 karakter yaz.
write(1, “bufsize2: “, 10) // stdouta 10 karakter
yaz

fd = open(argv[1], O_RDONLY); // argüman olarak


verilen dosyayı read only olarak aç
if(fd < 0) // dosya açılamazsa fd
değeri -1 olur
printf(”errno: %d\”, errno); // errno bir global
değişkendir. dosya bulunamadığı durumda değeri 2 olur.

while( (n = read(fd, buf, sizeof buf)) > 0){ // read


fd’den buf boyutu kadar karakteri buf’a yazar. read ve
write metodu üzerinde işlem yaptıkları karakter
//
sayısını return eder her seferinde
write(1, “*** “, 4);

ders notları 15
write(STDOUT_FILENO, buf, n); // buf’a
yazılanları stdouta yazar
}

close(fd); // fd serbest bırakılıyor


exit(0); // süreç sonlanırılıyor
return;
}

int main(){
int fd, n;
char buf[10]
close(1) // fd=1 serbest bırakılıyor
fd = open(”LS2”, O_WRONLY | O_TRUNC | O_CREATE,
0644) // boş olan ilk fd yani 1 LS2’ye atandı
sprintf(buf, “fd= %d\n”, fd);

write(1, buf, 8) // LS2’ye yazıldı


write(2, buf, 8); // stderr’e yazıldı
execl(”/bin/ls”, “ls”, “ -al”, 0); // ls-al komutu
normalde bilgileri write(1,..) kullanarak çalıştırır,
burada 1 LS2 olduğu için ls-al bilgisi LS2 dosyasına
yazılır
close(fd);
exit(0)
}

#define BUFFSIZE 8192


int main(){
int n;
char buf[BUFFSIZE]
while( (n=read(STDIN_FILENO, buf BUFFSIZE)) > 0){

ders notları 16
// STDIN_FILENO = 0, STDOUT_FILENO = 1. kütüphane
değişkenleri
if(write(STDOUT_FILENO, buf, n) ≠ n)
// kod stdin’den yazılanı okuyup stdouta yazıyor
printf(”write error”);
if(n < 0)
printf(”read error”);
}}

okuma yaparken 8kb’den daha fazla veri okumak istediğimizde bu iş


parçalara bölünerek yapılır. kullanılan buffsize’ın artırılması bu
durumu değiştirmez.
fprintf verisini önce buffera yazar. eğer buffer dolarsa veya sürecin
icrası sona ererse bufferdaki veri çıkışa yazılır.

sistem çağrıları buffer kullanmaz yani write buffera yazmaz. stderr’e


yapılan yazma işlemlerinde de buffer kullanılmaz.

int main(){
fprintf(stdout “%s “, “ABC”); // buffera
//fork(); // fork ile yeni
bir process oluşturulur. oluşturulan process
parentının bufferındaki verilerin kopyasına sahip olur
write(1, “DEF”, 3); // terminale
fprintf(stderr, “%s “, “GHI”) // terminale
fprintf(stdout, “%d”, getpid()); // buffera
write(2, “JKL”, 3) // terminale
for(i = 1 ; i < 5 ; i++){
fprintf(stdout, “%s”, “235”) // buffera
return 0;
} // DEF GHI JKL ABC pid 235. verilerin
görünme sırası

ders notları 17
int main(){
if(lseek(STDIN_FILENO, 0, SEEK_CUR) == -1) //
eğer stdin bir dosyaya verilmemişse konunlama yapamaz
printf(”cannot seek”)
else
printf(”seek ok”
}

lseek.exe < lseek2.c // stdin kaynak dosyaya


bağlandı, böyle konumlandırma yapabilir
> seek ok
cat lseek2.c | lseek2.exe // pipe’dan okuma işlerinde
sorun çıkar
> cannot seek

int main(){
int fd;
off_t offset, newoffset;
char *name, buf[BUFSIZ];

int(argc ≠ 3){
exit(1)
}
name = argv[1]
offset = atoi(argv[2])

if( (fd = open(name, O_RDONLY)) == -1


exit(1)

read(fd, buff, 5) // dosyaya 5


karakter yazdık

ders notları 18
new_offset = lseek(fd, offset, SEEK_CUR) // SEEK_CUR
5 karakter ileride, offset 20 olsun mesela
read(fd, buf, 5); // fp 25.
karakteri gösteriyor, okumaya 26. karakterden itibaren
başlanır
buf[5] = 0;
}

char buf1[] = “abcdefghij”, buf2[] = “ABCDEFGHIJ”;


int fd = create(”file.hole”, FILE_MODE) //
dosya oluşturulur
write(fd, buf1, 10) //
10 karakter yazılır
lseek(fd, 40, SEEK_SET) //
başlangıçtan itibaren 40 karakter ileri gidilir
write(fd, buf2, 10) //
10 karakter yazılır

// yani 10 karakter 30 karakter boşluk 10 karakter


olmak üzere 50 karakterlik dosya olur
// more ile bu dosyanın içeriğini göremezsin çünkü
more ilk hole’a kadar okur. cat ise hole’ları
görmezden gelerek dosya sonuna kadar okur
// od -c fileName ile tüm karakterleri görebilirsin

int main(){

char buf1[] = “abcd\n”


char buf2[] = “ABCDEFGHI\n”
int fd, pid;
fd = create(”LS”, 0644)
pid = fork() // child proces oluşturduk

ders notları 19
if(pid == 0){ // buraya sadece child
process girer
for(pid = 0 ; pid < 20000 ; pid++){ // 5 karakter
toplam 20.000 defa yazılır
write(fd, buf1, 5)
}
}
for(pid = 0; pid < 10000 ; pid++){ // parent
process 10 karakteri 10.000 defa yazar
write(fd, buf2, 10)
}
exit(0)
}
// iki process zaman paylaşımı ile yazar yani ikisinin
yazdıkları karışık sıradadır
// lakin parent child ilişkisi olduğu için ortak fd ve
fp kullanılır bu sebeple
// dosyanın boyutu 200.000 olur (20.000 x 5 + 10.000 x
10)

int main(){

char buf1[] = “abcd\n”


char buf2[] = “ABCDEFGHI\n”
int fd, pid;
pid = fork()
if(pid == 0){
fd = open(”LS”, O_WRONLY, 0644)
for(pid = 0 ; pid < 20000 ; pid++){
write(fd, buf1, 5)
}

ders notları 20
}
fd = open(”LS”, O_WRONLY, 0644)
for(pid = 0; pid < 10000 ; pid++){
write(fd, buf2, 10)
}
exit(0)
}
// burada her birinde farklı fp ve fd vardır bu
sebeple dosya boyutu 100.000 olur

#define STRSIZ 80
int main(){

int d;
int n = STRSIZ;
char fname[STRSIZ];
char buf[BUFSIZ];

if(argc ≠ 2){
exit(1)
}

strncpy(fname, argv[1], n) // dosya ismi fname’e


kopyalanıyor
fd = create(fname, S_IRUSR | S_IWUSR | S_IRGRP |
S_IROTH) // usera read, write, gruba read, other’a
read

strncpy(buf, “hello\n, sizeof buf);


write(fd, buf, strlen(buf) + 1)
close(fd)

ders notları 21
exit(0)
}

int main(){
puts(”begin”)
//printf(”begin”);
fork();
puts(”end”);
//printf(”end”)
} // puts buffera yazar, sonuna
kendiliğinden \n koyacağı için buffer verisi
boşaltılır begin end end yazılır.
// eğer ilk puts comment yapılır,
printf açılırsa printf’in buffera yazdığı veri childa
da aktarılacağı için begin end begin end yazılır

int main(){
int pid;
int status;
print parent pid by getpid
print parent of parent by getppid // parent
shelldir.

pid = fork();
if(pid == 0){ // child buraya girer
sleep(1) // 1 saniye cpu için uzun bir
süredir. bu sırada parentın icrası bitecektir
print child pid by getpid
print parent pid by getppid // 1 sonuç verir,
parentın icrası biteceği için init’in pid’si print
edilir
}

ders notları 22
else{
print parent pid by getpid
print child pid by pid
}
print “abc”
}
// çıkış
125
1304 // shell
125
39 // child
> // parentın icrası bitince shell yeni komut
satırı verir
39
1 // 125 değil 1 çünkü parentın icrası bitti

int main(){
int i = 5;
printf(”%d\n”, i);
execl(”./Y.exe”, “Y.exe”, 0); // buraya gelince
çalıştırılan kod komple değişir
printf(”%d”, i); // önce i değeri
yazılır, ardından hello. bu satır ise hiç
çalıştırılmaz
}
// Y.c
int main(){
printf(”hello”)
}

// üstteki koda status eklersek


int main(){

ders notları 23
int pid;
int status;
print parent pid by getpid
print parent of parent by getppid

pid = fork();
if(pid == 0){ // child buraya
girer
print child pid by getpid
print parent pid by getppid
sleep(1)
print parent pid by getppid
}
else{
print parent pid by getpid
print child pid by pid
wait(&status)
printf(”child is done by status: %d”, status);
}
}
// status eğer parentın en az bir tane çalışan çocuğu
varsa o çocuklardan sadece bir tanesinin icrasının
bitimine kadar bekleme yapar
// çıkış şöyle olacaktır
// parent → shell → parent, child, (childa geçtik,
onun bitmesini bekleyeceğiz), child, parent, sleep,
parent, done.
// burada forkdan önceki kod bitince önce child mı
yoksa önce parent mı icra edileceği konusu
tarifeleyiciye bağlıdır ama mantık aynı.

ders notları 24
bir süreç exec kullanmadan önce oluşturduğu fd'leri exec kullandıktan
sonra farklı bir programda da kullanmaya devam edebilir. sürecin id'si
de değişmeyecektir, o id'nin kullandığı fd'ler replacement işleminden
sonra halen geçerli olacaktır.

zombi süreçler bir süre daha sistemde kalırlar ve parentın çıkış


kodlarını okumalarını beklerler, eğer parentın icrası sona ererse onlar
da süreç tablolarından kaldırılırlar.

ders notları 25

You might also like