04- Dosya ve Dizin İşlemleri
Unix türevleri ile uğraşmaya başladığınızda, karşınıza şu konsept sıklıkla çıkacaktır: Everything is a file (Her şey bir dosyadır)
Bu konsept, farklı uzmanlar arasında fikir ayrılıklarına sebep olabilmektedir. Örneğin bazıları, her şeyin aslında bir dosya değil, bir dosya tanımlayıcı (file descriptor) olduğunu savunur.
İşletim sisteminin derinlikliklerine uzanan bu tartışmalarda, ipin ucunu fazla kaybetmeden yüzeye geri çıkalım. Zira işletim sisteminin derinliklerine - gerçek anlamda - indiğimizde, bir "dosyanın" ne olduğunu bile açıklamakta güçlük çekerim.
Ancak Linux ile uğraşacaksak, gerçekten de pek çok şeyin aslında bir dosya olduğunu, bu dosyaların da azımsanamayacak bir kısmının aslında plain-text olduğunu kabul ederek hayatımıza devam edebiliriz. Bu doküman serisinin içerisinde Metin İşleme bölümünün ayrıca ele alınacak olmasının temel sebebi de budur. Çünkü... Önemli!?!
Opsiyonlar Hakkında
Bu bölümde size anlatılacak opsiyonlar kesinlikle ezberlenmemeli. Şu an için birkaç basit iş yapacağız. Fakat Yardım Alma bölümünde, komutların nasıl kullanılacağına ve hangi opsiyonların ne işe yaradığına dair bilgileri nasıl edinebileceğimizi göreceğiz.
Boş Dosya Oluşturma
Boş bir dosya oluşturmak için yapabileceğimiz pek çok şey var. Bunlardan en sık kullanılanlarından biri de touch programıdır. touch programının esas amacı, dosyalara ait zaman damgalarını (erişim tarihi, değiştirme tarihi gibi) değiştirmektir. Fakat ifade ettiğiniz dosya, hâlihazırda yoksa, touch programı - varsayılan olarak - bu dosyayı boş şekilde oluşturur.
touch deneme komutu ile, "deneme" dosyasının zaman damgalarını değiştirmek istediğimizi belirttik. Fakat böyle bir dosya hâlihazırda bulunmadığı için bizim için oluşturuldu. Oluşturulan yeni dosyayı, ls programı sayesinde görebildik.
touch programı ile birden fazla dosyayı aynı anda oluşturmak da mümkün:
touch muzik resim deneme komutu ile, 3 farklı dosya oluşturmak istediğimizi belirttik. "deneme" dosyası zaten var olduğu için sadece erişim ve değiştirme tarihleri değiştirildi. "muzik" ve "resim" dosyaları olmadığı için, o dosyalar boş şekilde oluşturuldu.
Boş Dizin Oluşturma
Dizin oluşturmak için mkdir programını kullanırız. touch programına benzer şekilde, bir veya birden fazla dizini tek seferde oluşturabiliriz.
ali@ubuntu24:~$ mkdir tatil
ali@ubuntu24:~$ ls
deneme muzik resim tatil
ali@ubuntu24:~$ mkdir evraklar projeler tatil fotoğrafları
mkdir: cannot create directory ‘tatil’: File exists
ali@ubuntu24:~$ ls
deneme evraklar fotoğrafları muzik projeler resim tatil
Yukarıdaki çıktıları inceleyelim. mkdir tatil komutu ile "tatil" isimli bir dizin oluşturduk. ls ile listeledik ve "tatil" dizinini görebildik. Sonrasında ise "evraklar", "projeler" ve "tatil fotoğrafları" isimli 3 farklı dizin oluşturmayı denedik(!). Ancak başarılı olamadık.
Shell ile Tanışma yazısında bahsettiğimiz gibi, boşluk karakteri Bash için bir ayraçtır. Argümanları ayırır. Bu durumda Bash; komutumuzu "evraklar", "projeler", "tatil" ve "fotoğrafları" isimli dizinler oluşturacak şekilde yorumladı. Üstelik, "tatil" isimli dizini oluşturamadık. Çünkü zaten var. Fakat diğer dizinler - "fotoğrafları" dizini de dâhil, oluşturuldu.
Hatırlarsanız daha önce, çalıştırdığımız komutların hata ile karşılaşmadığı durumda sessizce işini yapacağından, fakat hata oluştuğunda bize haber vereceğinden bahsetmiştik. Yukarıda, bu durumun bir örneğini görüyoruz.
İsminde Boşluk Geçen Dosyalar
Bash'in boşluk karakterini bir ayraç olarak değil, gerçekten string bir boşluk olarak yorumlamasını istiyorsak, bunu şu 2 şekilde sağlayabiliriz. Birincisi, dosya ismini tırnak işaretleri arasına alabiliriz. mkdir "tatil fotoğrafları" gibi. İkinci bir yöntem olarak ise, escape character dediğimiz özel karakteri kullanabiliriz. Bu konuya daha sonra değineceğiz. Fakat şu an için, mkdir tatil\ fotoğrafları gibi bir kullanım şekli olduğundan bahsedebiliriz.
Dosya ve Dizin Kopyalama
Kopyalama işlemlerimiz için cp programını kullanabiliriz. Kabaca, cp kaynak hedef şeklinde bir kullanımı vardır.
ali@ubuntu24:~$ ls
deneme evraklar fotoğrafları muzik projeler resim tatil
ali@ubuntu24:~$ cp muzik house
ali@ubuntu24:~$ ls
deneme evraklar fotoğrafları house muzik projeler resim tatil
Yukarıdaki örnekte, ls ile var olan dosyalarımızı listeledik. Devamında "muzik" dosyasının bir kopyasını, "house" ismiyle oluşturmak istedik. Tekrar listelediğimizde ise dosyamızın bir kopyasını oluşturmuş olduk.
Aynı işlemi, "tatil" dizini için deneyelim:
cp programı, varsayılan olarak dosyaları kopyalar. Bir dizini, tüm içeriği ile birlikte kopyalamak için "-R, -r, --recursive" opsiyonlarından herhangi birini kullanabiliriz. Aldığımız hata mesajı da zaten buna benzer bir öneride bulunuyor.
ali@ubuntu24:~$ cp -r tatil izmir
ali@ubuntu24:~$ ls
deneme evraklar fotoğrafları house izmir muzik projeler resim tatil
"-r" opsiyonu sayesinde, "tatil" dizininin bir kopyasını, "izmir" olarak oluşturduk.
Şimdi de "deneme" dosyasını, "projeler" dizini içine kopyalayalım:
ali@ubuntu24:~$ cp deneme projeler/
ali@ubuntu24:~$ ls
deneme evraklar fotoğrafları house izmir muzik projeler resim tatil
ali@ubuntu24:~$ ls projeler/
deneme
İlk komut ile, kaynak dosya olarak "deneme" dosyasını gösterdik. Hedef olarak ise "projeler" dizinini belirttik. ls ile baktığımızda hiçbir değişiklik yok. Normal. Fakat ls projeler/ komutu ile, "projeler" dizininin içini listelediğimizde, orada "deneme" dosyasını görüyoruz.
Sondaki "/" Karakteri
Dizinleri belirtirken sonlarında yer alan "/" karakterini her zaman koymak zorunda değilsiniz. Fakat komutlarınızı otomatik tamamlattığınızda (TAB ile), Bash bu işareti koyacaktır. Bu, esasında iyi bir pratiktir. Komutunuzu yazarken neyin dosya, neyin dizin olduğunu rahatlıkla görebilmenize olanak tanır.
Kopyalama sırasında hedef belirtirken, farklı bir dosya ismi de verebilirsiniz. Yani "deneme" dosyasını, "projeler" dizini içerisinde, "web projesi" gibi bir isimle kopyalayabiliriz. Dikkat edin! Dosya isminde boşluk olduğu için tırnak işaretlerini kullanmalıyız.
ali@ubuntu24:~$ cp deneme "projeler/web projesi"
ali@ubuntu24:~$ ls projeler/
deneme 'web projesi'
ali@ubuntu24:~$
Gördüğünüz gibi "deneme" dosyasını, farklı bir isimle kopyalamış olduk.
Taşıma & Yeniden Adlandırma
Bu iki konu için de mv programını kullanabiliriz. Hedef olarak bir dizin belirtirsek, kaynak dosyamızı oraya taşır. Şayet bir dizin belirtmezsek, dosyanın ya da dizinin ismini değiştirir.
ali@ubuntu24:~$ ls
deneme evraklar fotoğrafları izmir muzik projeler resim tatil
ali@ubuntu24:~$ mv deneme örnek
ali@ubuntu24:~$ ls
evraklar fotoğrafları izmir muzik örnek projeler resim tatil
ali@ubuntu24:~$ mv fotoğrafları "tatil fotoğrafları"
ali@ubuntu24:~$ ls
evraklar izmir muzik örnek projeler resim tatil 'tatil fotoğrafları'
mv deneme örnek ile, "deneme" dosyasının adını "örnek" olarak değiştirdik. mv fotoğrafları "tatil fotoğrafları" komutu ile, "fotoğrafları" isimli dizinin adını "tatil fotoğrafları" olarak değiştirdik.
ali@ubuntu24:~$ ls
evraklar izmir muzik örnek projeler resim tatil 'tatil fotoğrafları'
ali@ubuntu24:~$ mv örnek evraklar/
ali@ubuntu24:~$ mv resim evraklar/
ali@ubuntu24:~$ ls
evraklar izmir muzik projeler tatil 'tatil fotoğrafları'
ali@ubuntu24:~$ ls evraklar/
örnek resim
Burada ise sırasıyla "örnek" ve "resim" dosyalarını "evraklar" dizini içerisine taşıdık. ls ile tekrar baktık ve bu dosyaları göremedik. ls evraklar/ ile "evraklar" dizininin içeriğini listelediğimizde ise, "örnek" ve "resim" isimli 2 dosyamızın buraya taşındığını gördük.
Boş Dizinleri Silme
rmdir komutu ile, içi boş olan dizinleri silebiliriz.
ali@ubuntu24:~$ ls
evraklar izmir muzik projeler tatil 'tatil fotoğrafları'
ali@ubuntu24:~$ rmdir izmir
rmdir: failed to remove 'izmir': Directory not empty
ali@ubuntu24:~$ rmdir tatil
ali@ubuntu24:~$ ls
evraklar izmir muzik projeler 'tatil fotoğrafları'
rmdir izmir komutu ile "izmir" dizinini silmek istedik. Fakat dizin boş olmadığı için komutumuz hata verdi. rmdir tatil komutu ile ise "tatil" dizinini silmek istedik ve herhangi bir sorun ile karşılaşmadık.
Dosya ve Dolu Dizinleri Silme
Her iki işlem için de rm programını kullanacağız.
ali@ubuntu24:~$ ls
evraklar izmir muzik projeler 'tatil fotoğrafları'
ali@ubuntu24:~$ rm muzik
ali@ubuntu24:~$ ls
evraklar izmir projeler 'tatil fotoğrafları'
ali@ubuntu24:~$ rm izmir
rm: cannot remove 'izmir': Is a directory
ali@ubuntu24:~$ ls
evraklar izmir projeler 'tatil fotoğrafları'
ali@ubuntu24:~$ rm -r izmir
ali@ubuntu24:~$ ls
evraklar projeler 'tatil fotoğrafları'
rm muzik komutu ile "muzik" dosyasını sildik. rm izmir komutu ile dizini silmeyi denedik fakat bu sefer de bir dizin olduğu için silemedik. Daha sonra rm -r izmir komutu ile bu dizini ve içindeki dosyaları silebildik. Tıpkı cp programına benzer şekilde, rm programı da dizinler üzerinde çalışabilmek için "-r, -R veya --recursive" opsiyonlarına ihtiyaç duyar.
Opsiyonlar Hakkında Tekrar Hatırlatma
Buraya kadar olan kısımda birkaç komut gördük. Bunlarla birtakım işlemler yaptık. Bazı opsiyonlara ihtiyaç duyduk. Ancak tekrar etmekte yarar görüyorum. Bu opsiyonlar ezberlenecek şeyler değil. Yardım Alma bölümünde, bu opsiyonların listesine nasıl ulaşacağımızdan detaylıca bahsedeceğiz.
Komut mu, program mı?
İfadelerimde bazen komut, bazen program kullandığımı fark etmiş olabilirsiniz. "Komut"; CLI'a yazıp, "Enter"a basıp gönderdiğiniz satırdır. Bizim burada kullandığımız ls, cp, mv gibi araçlar ise birer "program"dır. Internal ve External Komutlar bölümünde, bu ayrımdan daha detaylı bahsedeceğiz. Bu ayrımı bilmek çok önemli olmakla birlikte, bu iki kelimenin birbiri yerine kullanıldığına da - maalesef - şahit olacaksınız.
Metin Dosyalarını Okuma
Metin (text) dosyalarını okumak için kullanabileceğimiz birçok araç mevcut. Bunlardan birkaçına değineceğiz.
Okunacak Dosyalar
Bu bölümde bazı dosyalar okuyacağız. Bu dosyaların ne olduğu ve ne işe yaradığı, şu an için bizi ilgilendirmeyecek.
cat
Dosyaların içeriğini okumak için kullanabileceğimiz programlardan biri cat. cat, dosyaları birleştirir ve çıktıyı ekranınıza yazar. Şayet tek dosya verirseniz, sadece bir dosyayı okumanıza olanak sağlar.
ali@ubuntu24:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin
dhcpcd:x:100:65534:DHCP Client Daemon,,,:/usr/lib/dhcpcd:/bin/false
messagebus:x:101:102::/nonexistent:/usr/sbin/nologin
systemd-resolve:x:992:992:systemd Resolver:/:/usr/sbin/nologin
pollinate:x:102:1::/var/cache/pollinate:/bin/false
polkitd:x:991:991:User for polkitd:/:/usr/sbin/nologin
syslog:x:103:104::/nonexistent:/usr/sbin/nologin
uuidd:x:104:105::/run/uuidd:/usr/sbin/nologin
tcpdump:x:105:107::/nonexistent:/usr/sbin/nologin
tss:x:106:108:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:107:109::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:989:989:Firmware update daemon:/var/lib/fwupd:/usr/sbin/nologin
usbmux:x:108:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
ali:x:1000:1000:Ali:/home/ali:/bin/bash
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
ali@ubuntu24:~$
cat /etc/passwd komutu ile, "/etc/passwd" dosyasını okumak istediğimizi belirttik. Bu dosyanın içeriği, shell'imize geldi. cat programının "-n" opsiyonu ile, okunan dosyaya satır numaraları eklemek de mümkün:
ali@ubuntu24:~$ cat -n /etc/apt/sources.list.d/ubuntu.sources
1 Types: deb
2 URIs: http://archive.ubuntu.com/ubuntu/
3 Suites: noble noble-updates noble-backports
4 Components: main restricted universe multiverse
5 Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
6
7 Types: deb
8 URIs: http://security.ubuntu.com/ubuntu/
9 Suites: noble-security
10 Components: main restricted universe multiverse
11 Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
nl
nl programı, bir dosyadaki satırları numaralandırarak ekrana yazar. nl programı ile, cat -n çıktısına benzer bir çıktı alabiliriz.
ali@ubuntu24:~$ nl /etc/crontab
1 # /etc/crontab: system-wide crontab
2 # Unlike any other crontab you don't have to run the `crontab'
3 # command to install the new version when you edit this file
4 # and files in /etc/cron.d. These files also have username fields,
5 # that none of the other crontabs do.
6 SHELL=/bin/sh
7 # You can also override PATH, but by default, newer versions inherit it from the environment
8 #PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
9 # Example of job definition:
10 # .---------------- minute (0 - 59)
11 # | .------------- hour (0 - 23)
12 # | | .---------- day of month (1 - 31)
13 # | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
14 # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
15 # | | | | |
16 # * * * * * user-name command to be executed
17 17 * * * * root cd / && run-parts --report /etc/cron.hourly
18 25 6 * * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; }
19 47 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; }
20 52 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; }
21 #
more
more, dosya içeriklerini sayfa sayfa okumamızı sağlayan bir sayfalayıcıdır (pager). Kullanımı, cat ve nl programlarına benzer olmakla birlikte, en önemli farkı, içeriği tek seferde değil, sayfa sayfa vermesidir.
ali@ubuntu24:~$ more /var/log/auth.log
2025-09-07T23:42:04.794798+00:00 ubuntu24 useradd[844]: new group: name=ali, GID=1000
2025-09-07T23:42:04.794801+00:00 ubuntu24 useradd[844]: new user: name=ali, UID=1000, GID=1000, home=/home/ali, shell=/bin/bash, from=none
2025-09-07T23:42:04.794803+00:00 ubuntu24 useradd[844]: add 'ali' to group 'adm'
2025-09-07T23:42:04.794804+00:00 ubuntu24 useradd[844]: add 'ali' to group 'cdrom'
2025-09-07T23:42:04.794807+00:00 ubuntu24 useradd[844]: add 'ali' to group 'sudo'
2025-09-07T23:42:04.794829+00:00 ubuntu24 useradd[844]: add 'ali' to group 'dip'
2025-09-07T23:42:04.794835+00:00 ubuntu24 useradd[844]: add 'ali' to group 'plugdev'
2025-09-07T23:42:04.794838+00:00 ubuntu24 useradd[844]: add 'ali' to group 'lxd'
2025-09-07T23:42:04.794841+00:00 ubuntu24 useradd[844]: add 'ali' to shadow group 'adm'
2025-09-07T23:42:04.794844+00:00 ubuntu24 useradd[844]: add 'ali' to shadow group 'cdrom'
2025-09-07T23:42:04.794847+00:00 ubuntu24 useradd[844]: add 'ali' to shadow group 'sudo'
2025-09-07T23:42:04.794850+00:00 ubuntu24 useradd[844]: add 'ali' to shadow group 'dip'
2025-09-07T23:42:04.794870+00:00 ubuntu24 useradd[844]: add 'ali' to shadow group 'plugdev'
2025-09-07T23:42:04.794874+00:00 ubuntu24 useradd[844]: add 'ali' to shadow group 'lxd'
2025-09-07T23:42:04.794878+00:00 ubuntu24 passwd[852]: password for 'ali' changed by 'root'
..........
more programını kullanırken, "SPACE" tuşu ile bir sonraki sayfaya geçebilir, "q" tuşu ile programdan çıkabilirsiniz.
less
more programının tersi olarak tanımlanmıştır. more programına benzer şekilde, yine bir pager'dır. Fakat içeriği sayfa sayfa göstermek yerine, satır satır gezebilmenize olanak tanır. Yön tuşlarınızı kullanarak bu gezintiyi sağlayabilirsiniz. "q" tuşu ile programdan çıkabilirsiniz.
Kullanımı yine less <dosya adı> şeklindedir. Örneğin: less /var/log/bootstrap.log
less vs. more
less programı, more programına kıyasla daha yeni ve - bence - kullanımı daha rahat olan bir programdır. Fakat karşımıza ne çıkacağını bilemeyiz. Bazen, eski bir sistemle çalışmak durumunda kalabiliriz. Bu nedenle, bu iki pager'ı da kullanabilir olmak önemlidir.
Peki Şimdi?
Aslında dosya işlemleri ile ilgili temel bazı programlara değindik. Fakat bunları daha efektif kullanabilmek için, Bağıl ve Mutlak Yol kavramına da değinmemiz gerekiyor. Tabii bu programların çok çeşitli ve işimizi oldukça kolaylaştıracak farklı opsiyonları da var. Yeri geldikçe, bunlara da değineceğiz.
Deneyin
Okurken/dinlerken her şey çok güzel ve kolay gelebilir. Lütfen bu komutları deneyin. Hatalar yapın. Kurcalayın. Aksi durumda aşinalık kazanmanız oldukça zorlaşacaktır.