chmod 755 ve u+x farkı: Sayısal ve sembolik modlar
Linux chmod komutunda sayısal ve sembolik mod kullanımı arasındaki farkları öğrenin. Dizinlerdeki izin hatalarını gidermek için büyük X parametresinin neden gerekli olduğunu inceleyin.
chmod neyi değiştirir
chmod bir dosya veya dizin üzerindeki izin bitlerini değiştirir ve bu bitleri iki farklı gösterim biçiminden biriyle kabul eder. Sayısal biçim, tüm izin bitlerini aynı anda değiştiren sekizlik (octal) bir sayıdır. Sembolik biçim ise bir kullanıcı sınıfı ve bir operatör tanımlar; yalnızca belirttiğiniz bitleri düzenler. Her iki yöntem de aynı sistem çağrısı ile sonuçlanır. Aradaki fark, belirtmediğiniz bitlere ne olduğudur.
Bir modu okumak ile bir modu değiştirmek farklı işlemlerdir. Uzun listelemedeki harfler henüz net değilse, önce drwxr-xr-x ifadesinin alan bazlı anlamı konusunu okuyun. Bu kılavuz yalnızca izinleri değiştirmeye odaklanır.
Buradaki her şeyi normal kullanıcı hesabınızla çalıştırın. root hesabı bu denetimleri atlar; bu nedenle root olarak yapılan bir izin gösterimi hiçbir şeyi kanıtlamaz. Yeni bir sunucuda hala root olarak çalışıyorsanız, en az yetkiye sahip normal bir kullanıcı oluşturun ve geri dönün.
Atılabilir bir sandbox kurulumu
cd "$(mktemp -d)"
touch notes.txtmktemp -d, /tmp altında boş bir dizin oluşturur ve oluşturduğu yolu ekrana yazdırır; komut ikamesi ise bu yolu doğrudan cd komutuna aktarır. Aşağıdaki işlemlerin hiçbiri, sizin için önemli olan dosyalara dokunmaz.
Tek bir komut, her değişikliğin sonucunu raporlar:
stat -c '%a %A %n' notes.txt%a modu sekizlik (octal) sayı olarak, %A aynı modu uzun listelemede kullanılan harf biçiminde, %n ise dosya adını yazdırır. Takip eden bloklarda, $ ile başlayan satır sizin yazdığınız komutu, altındaki satır ise komutun çıktısını temsil eder. Komutları kendiniz çalıştırın. Sayısal mod ortamınızdaki hiçbir şeye bağlı olmadığından, makinenizdeki çıktı satırı satırına eşleşmelidir.
Sayısal biçim: her sınıf için bir sekizlik basamak
İlk basamak dosya sahibine aittir. İkinci basamak dosyanın grubuna aittir. Üçüncü basamak ise diğer herkes içindir. Her basamak, bit başına bir değer düşecek şekilde yapılan bir toplamdır. Her seferinde bir biti ayarlayın ve stat komutunun ne raporladığını inceleyin.
$ chmod 400 notes.txt
$ stat -c '%a %A %n' notes.txt
400 -r-------- notes.txt
$ chmod 200 notes.txt
$ stat -c '%a %A %n' notes.txt
200 --w------- notes.txt
$ chmod 100 notes.txt
$ stat -c '%a %A %n' notes.txt
100 ---x------ notes.txtHarfler basamaklarla hizalanır. Dosya türünü belirten ilk karakterden sonra, üç harften oluşan ilk grup sahibine, sonraki üç grup grubuna ve son üçü diğer herkese aittir. Bir sınıf içindeki bitleri birleştirmek için değerleri toplayın.
$ chmod 600 notes.txt
$ stat -c '%a %A %n' notes.txt
600 -rw------- notes.txt
$ chmod 700 notes.txt
$ stat -c '%a %A %n' notes.txt
700 -rwx------ notes.txt
$ chmod 750 notes.txt
$ stat -c '%a %A %n' notes.txt
750 -rwxr-x--- notes.txtSayısal mod mutlak bir değerdir. Her çalıştırıldığında dokuz bitin tamamını yazar, bu nedenle üzerinde düşünmediğiniz bir sınıf da yazılmış olur.
$ chmod 755 notes.txt
$ stat -c '%a %A %n' notes.txt
755 -rwxr-xr-x notes.txt
$ chmod 600 notes.txt
$ stat -c '%a %A %n' notes.txt
600 -rw------- notes.txtİkinci komut grup veya diğer herkes hakkında hiçbir şey belirtmedi, ancak bitleri yine de değişti. Sayısal biçimin doğası budur ve küçük bir düzenleme için yanlış araç olmasının nedeni de budur. (chmod ayrıca, bunların önündeki dördüncü bir basamakta yer alan setuid, setgid ve sticky bitlerini de yönetir. Bu ayrı bir konudur ve bu kılavuz üç basamaklı yapı ile sınırlı kalmaktadır.)
Sembolik biçim: bir sınıf, bir operatör ve ardından bitler
Önce sınıfı yazın. u sahibidir, g gruptur, o diğer herkesi temsil eder ve a bunların hepsini birden ifade eder. Ardından operatörü ekleyin: + bit ekler, - bitleri kaldırır ve = söz konusu sınıfı tam olarak listelediğiniz bitlere ayarlar ve geri kalan bitlerini temizler. Son olarak, r, w veya x olarak bitlerin kendisini belirtin.
$ chmod 640 notes.txt
$ stat -c '%a %A %n' notes.txt
640 -rw-r----- notes.txt
$ chmod u+x notes.txt
$ stat -c '%a %A %n' notes.txt
740 -rwxr----- notes.txt
$ chmod g-r notes.txt
$ stat -c '%a %A %n' notes.txt
700 -rwx------ notes.txt
$ chmod o=r notes.txt
$ stat -c '%a %A %n' notes.txt
704 -rwx---r-- notes.txtHer komut bir sınıfa müdahale eder ve diğerlerini olduğu gibi bırakır. Yan tümceleri boşluk bırakmadan virgülle birleştirin; chmod bunları soldan sağa doğru uygular.
$ chmod u=rw,go=r notes.txt
$ stat -c '%a %A %n' notes.txt
644 -rw-r--r-- notes.txt
$ chmod go= notes.txt
$ stat -c '%a %A %n' notes.txt
600 -rw------- notes.txtEşittir işaretinden sonra hiçbir şey gelmeyen go=, gruptan ve diğer herkesten tüm bitleri alır. Bu, yalnızca sahibinin okuyabileceği bir dosya için, örneğin bir SSH anahtar çiftinin özel kısmı için istediğiniz biçimdir.
chmod kendi yaptığı işi raporlayabilir; bu, ekranın izlenmediği bir betik içerisinde önemlidir.
chmod -v u+x notes.txt
chmod -v u+x notes.txt-v, kendisine verilen her dosya için bir satır yazdırır. Her iki komutu da çalıştırın ve ekranınızdaki iki satırı karşılaştırın: ilki dosya adını belirtir ve modun hangi değerden hangi değere değiştiğini raporlar; ikincisi ise modun korunduğunu bildirir, çünkü eklenmesi istenen bit zaten ayarlanmıştır. -c yalnızca bir dosya gerçekten değiştiğinde bir satır yazdırır, bu nedenle bir günlükte tutmak için daha uygun olan budur.
chmod 755 ile u+x karşılaştırması: hangi notasyon kullanılmalı
Aynı dosyadan iki kez başlayın ve her notasyonun geride ne bıraktığını karşılaştırın.
$ chmod 640 notes.txt
$ chmod 755 notes.txt
$ stat -c '%a %A %n' notes.txt
755 -rwxr-xr-x notes.txt
$ chmod 640 notes.txt
$ chmod u+x notes.txt
$ stat -c '%a %A %n' notes.txt
740 -rwxr----- notes.txtHer iki komut da dosyayı sahibi için çalıştırılabilir hale getirdi. Sadece biri diğer iki sınıfı olduğu gibi bıraktı. Tam olarak istediğiniz nihai durumu biliyorsanız ve bunun uygulanmasını istiyorsanız sayısal mod kullanın; daha önce hiç görmediğiniz bir makinede aynı sonucu üretmesi gereken bir dağıtım betiğinde dürüst yaklaşım budur. Aklınızdaki cümlede ekle veya kaldır ifadeleri geçiyorsa sembolik mod kullanın, çünkü sayısal formun o kısmı olduğu gibi bırak deme şansı yoktur.
Yeni bir dosyanın başlangıç modu chmod ile belirlenmez. Bu, dosyayı oluşturan sürecin umask değerinden gelir. Orada geçerli olan değeri görmek için kendi kabuğunuzda umask ve umask -S komutlarını çalıştırın; bu değerin dağıtımlar arasında, oturum açtığınız kabuk ile bir systemd servisi arasında ve farklı hesaplar arasında farklılık göstereceğini unutmayın. umask her yeni dosyanın modunu belirler, bu nedenle chmod çalışmadan önce başlangıç noktanızın ne olduğuna o karar verir.
Dizinlerdeki execute bitinin işlevi
Bu, en çok zaman kaybettiren yanlış anlaşılmalardan biridir. Normal bir dosyada execute biti, çekirdeğin dosyayı çalıştırabileceğini belirtir. Bir dizin herhangi bir komut içermediğinden, çalıştırılacak bir şey yoktur. Dizinlerde ise execute biti, geçiş (traversal) anlamına gelir: yani dizin içindeki bir ismi çözümleme izni. dir/file yoluna ulaşmak için dir üzerinde bu izne sahip olmanız gerekir. Read biti ise ayrı bir izindir ve dizinin içerdiği isimleri listelemenize olanak tanır. Birini diğerine sahip olmadan da kullanabilirsiniz; bunu bizzat gözlemlediğinizde durumun mantığını kavramak daha kolay olacaktır.
$ mkdir vault
$ printf 'hello\n' > vault/secret.txt
$ chmod 600 vault/secret.txt
$ chmod 100 vault
$ echo vault/*
vault/*
$ cat vault/secret.txt
helloShell, kalıbı değiştirmeden geri yazdı çünkü vault/* genişletme işlemi dizini okumayı gerektirir ve hiçbir şeyle eşleşmeyen bir glob, hata vermek yerine olduğu gibi literal metin olarak aktarılır. cat yine de çalıştı çünkü ismi kendiniz belirttiniz ve geçiş izni mevcuttu. Şimdi iki biti birbiriyle değiştirin.
$ chmod 400 vault
$ echo vault/*
vault/secret.txt
$ cat vault/secret.txt
cat: vault/secret.txt: Permission deniedİsimler görünür durumdadır ancak içeriklere erişilemez. Read biti size listeyi verir. Execute biti ise içeri girmenize olanak tanır. Kullandığınız hemen hemen her dizin her iki izne de ihtiyaç duyar.
$ chmod 500 vault
$ cat vault/secret.txt
helloNeden sayisal mod ile kullanilan chmod -R komutu bir dizin agacina zarar verir
-R komutu tum dizin agacini tarar ve karsilastigi her dosyaya verdiginiz modu uygular. Bir dizin ile bir veri dosyasi farkli izin bitlerine gereksinim duyar; bu nedenle tek bir mutlak sayi her ikisi icin de dogru olamaz. Kucuk bir dizin agaci olusturun ve hatalarin nasil olustugunu gozlemleyin.
$ mkdir -p site/css
$ touch site/index.html site/css/main.css
$ printf '#!/bin/bash\necho hi\n' > site/deploy.sh
$ chmod 755 site site/css site/deploy.sh
$ chmod 644 site/index.html site/css/main.css
$ stat -c '%a %A %n' site site/css site/index.html site/css/main.css site/deploy.sh
755 drwxr-xr-x site
755 drwxr-xr-x site/css
644 -rw-r--r-- site/index.html
644 -rw-r--r-- site/css/main.css
755 -rwxr-xr-x site/deploy.shBu yapi, statik dosyalardan olusan bir dizinin gereksinim duydugu duzendir. Iste ilk yinelemeli hata:
$ chmod -R 755 site
$ stat -c '%a %A %n' site/index.html site/css/main.css
755 -rwxr-xr-x site/index.html
755 -rwxr-xr-x site/css/main.cssHicbir sey bozulmadi, sorun da tam olarak budur. Bu hata sessizce gerceklesir, bu yuzden yillarca kopyalanan talimatlar icinde varligini surdurur. Iki veri dosyasi artik program gibi davranir. Git, calistirma bitini (execute bit) saklar; bu nedenle bir sonraki commit isleminiz bu degisikligi depoyu klonlayan herkese tasir ve rsync ile tar komutlari bunu kopyaladiginiz her makineye goturur.
Ikinci yinelemeli hata ise belirgindir. Calistirma biti icermeyen bir modu bir dizine uygularsaniz, dizin erisime kapanir.
$ chmod 644 site
$ stat -c '%a %A %n' site
644 drw-r--r-- site
$ echo site/*
site/css site/deploy.sh site/index.html
$ cd site
bash: cd: site: Permission denied
$ cat site/index.html
cat: site/index.html: Permission deniedOkuma biti (read bit) korundugu icin dosya isimleri hala listelenir, ancak calistirma biti kaldirildigi icin dizin icindeki her yol erisime kapanir. chmod -R 644 site komutu, dizin agacindaki her dizine bunu tek seferde uygular. Sonrasinda karsilastiginiz durum her zaman tutarli olmayabilir; cunku chmod, erisim yetkisini kaldirdigi dizinlerin icinden gecmek zorundadir. Bu yuzden varsayimda bulunmak yerine, find site -type d -exec stat -c '%a %n' {} + ile nelerin degistigini kontrol edin. Devam etmeden once bu durumu eski haline getirin.
$ chmod 755 site
$ chmod 644 site/index.html site/css/main.css
$ stat -c '%a %A %n' site site/index.html
755 drwxr-xr-x site
644 -rw-r--r-- site/index.htmlYinelemeli bir chmod isleminin geri almasi yoktur. chmod, degistirdigi degerleri kaydetmez; bu nedenle onarim islemi size kalir ve izinleri eski hallerine getirmek icin manuel olarak yeniden yapilandirmaniz gerekir. Bu islem, yanlislikla silinen dosyalarin rm -rf sonrasi kurtarilmasi ile ayni derecede yavas ve belirsiz bir istir. Cikarilacak ders ise aynidir: Yinelemeli bir komutu calistirmadan once hedefini kontrol edin.
Büyük X: her dosyada değil, dizinlerde yürütme
Sembolik modlar X ifadesinin yanı sıra x ifadesini de kabul eder. X, yürütme bitini yalnızca mantıklı olduğu durumlarda ayarlar: bir dizinde veya zaten herhangi bir sınıf için yürütme bitine sahip olan normal bir dosyada. Bu kural, tam olarak -R ifadesinin izlemesini istediğiniz kuraldır.
$ chmod -R u=rwX,go=rX site
$ stat -c '%a %A %n' site site/css site/index.html site/css/main.css site/deploy.sh
755 drwxr-xr-x site
755 drwxr-xr-x site/css
644 -rw-r--r-- site/index.html
644 -rw-r--r-- site/css/main.css
755 -rwxr-xr-x site/deploy.shTek bir komutla dizinler erişilebilir durumda kalırken veri dosyalarına dokunulmadı. Betik, zaten bir yürütme bitine sahip olduğu için bu bitini korudu; bu da X kuralının ikinci yarısıdır. X, bir dosyanın o anki modunu okur, bu nedenle tüm yürütme bitlerini kaybetmiş bir dosya bu komutla geri getirilemez.
$ chmod 644 site/deploy.sh
$ chmod -R u=rwX,go=rX site
$ stat -c '%a %A %n' site/deploy.sh
644 -rw-r--r-- site/deploy.sh
$ site/deploy.sh
bash: site/deploy.sh: Permission denied
$ chmod u+x site/deploy.sh
$ stat -c '%a %A %n' site/deploy.sh
744 -rwxr--r-- site/deploy.sh
$ site/deploy.sh
hiAynı kural tersi yönde de çalışır. X, bir dosyanın zaten sahip olduğu bir yürütme bitini başka bir sınıfa genişletir:
$ chmod go+X site/deploy.sh
$ stat -c '%a %A %n' site/deploy.sh
755 -rwxr-xr-x site/deploy.shYani küçük harfli x, çalıştırılabilir hale getirmek istediğiniz tek bir dosya içindir; X ise bir ağaç yapısı üzerinde toplu işlem yapmak içindir. Mevcut moda dayalı bir kural yerine, her tür nesne için kesin bir mod istediğinizde, tarama işlemini find ile ayırın.
find site -type d -exec chmod 755 {} +
find site -type f -exec chmod 644 {} +
chmod u+x site/deploy.sh-type d dizinleri, -type f ise normal dosyaları seçer; böylece her tür, sahip olması gereken modu alır. -exec ... +, dosya başına bir süreç başlatmak yerine birçok yolu tek bir chmod çağrısında toplar; bu durum, binlerce öğe içeren bir ağaç yapısında önem taşır. Betik, yürütme bitini ayrı bir satırda, bilinçli olarak geri alır.
Uzaklaşmadan önce sonucu kontrol edin
Herhangi bir özyinelemeli (recursive) değişiklikten sonra önemli hataları bulmak için iki komut kullanılır. İlki, artık içine giremeyeceğiniz dizinleri listeler.
find . -type d ! -perm -u+xİkincisi, makinedeki herhangi bir hesabın düzenleyebileceği dosyaları listeler.
find . -type f -perm -o+w-perm -o+w içinde, baştaki - ifadesi en az bu bitler anlamına gelir; bu nedenle, başka hangi bitler ayarlanmış olursa olsun, o sınıfının yazma bitini içerdiği bir dosyayla eşleşir. Her iki komutun da hiçbir çıktı vermemesi, hedeflenen sonuçtur. Her iki komutu da -R ile yeni değiştirdiğiniz herhangi bir dizin ağacının en üstünden çalıştırın ve değiştirmeyi amaçladığınız birkaç yol üzerinde stat -c '%a %A %n' komutunu uygulayın; böylece ayarladığınızı düşündüğünüz mod ile çekirdeğin (kernel) gerçekten tuttuğu mod aynı olur.
FAQ
chmod 755 ile chmod u+x arasındaki fark nedir?
Sayısal mod mutlak bir değerdir. Dosya üzerindeki tüm izin bitlerini yeniden yazar, bu nedenle üzerinde düşünmediğiniz sınıflar da yeniden yazılmış olur. Sembolik mod ise bir düzenlemedir. u+x, dosya sahibi için bir bit ekler ve diğer tüm bitleri olduğu gibi bırakır. Bir dosya üzerinde tam olarak istediğiniz nihai durumu bildiğinizde sayısal formu kullanın. Tek bir şeyi eklemek veya kaldırmak istediğinizde sembolik formu kullanın. Her iki komuttan önce ve sonra stat -c '%a %A %n' <file> çalıştırırsanız, aradaki fark çıktıda görülecektir.
Web dosyalarının bulunduğu bir dizinde chmod -R 755 kullanmak neden kötü bir fikirdir?
Çünkü -R, aynı mutlak modu hem dizinlere hem de normal dosyalara uygular; oysa bu ikisinin farklı bitlere ihtiyacı vardır. Bir dizinin gezilebilir olması için çalıştırma (execute) bitine ihtiyacı vardır. HTML ve CSS gibi veri dosyalarının buna ihtiyacı yoktur; bunları çalıştırılabilir olarak işaretlemek, git tarafından bir sonraki commit işleminizde kaydedilen ve rsync tarafından bir sonraki makineye kopyalanan bir değişikliktir. Çalıştırma bitinin yalnızca dizinlere uygulanması için chmod -R u=rwX,go=rX <dir> kullanın veya her türün kendi modunu alması için -type d ve -type f ile find üzerinden işlem yapın.
Bir dizin üzerindeki çalıştırma biti ne işe yarar?
Çalıştırma değil, geçiş izni sağlar. Bir dizinin içinde çalıştırılacak bir şey yoktur. Çalıştırma biti, dizin içindeki bir ismin çözümlenmesi için gereken izindir; bu nedenle, yolun sonundaki dosyayı açabilmeniz için o yoldaki her dizinde bu bitin olması gerekir. Okuma biti ayrıdır ve isimlerin listelenmesine izin verir. Birini diğerinden bağımsız tutabilirsiniz: yalnızca çalıştırma izniyle, ismini bildiğiniz bir dosyayı açabilirsiniz ancak shell o dizindeki bir glob ifadesini genişletemez; yalnızca okuma izniyle ise isimleri görebilirsiniz ancak dosyayı açmaya yönelik her girişim başarısız olur.
Küçük x yerine ne zaman büyük X kullanmalıyım?
Komut özyinelemeli (recursive) olduğunda her zaman X kullanın. X, çalıştırma bitini dizinlere ayarlar; normal dosyalarda ise yalnızca zaten bir çalıştırma biti ayarlanmışsa bu biti atar. Böylece tek bir geçişle, veri dosyalarını programlara dönüştürmeden bir ağacı gezilebilir hale getirirsiniz. Tek bir dosyayı işaret ettiğinizde ve sadece o dosyayı kastettiğinizde küçük x kullanın. Unutulmaması gereken bir sınır vardır: X, bir dosya üzerinde tamamen temizlenmiş bir çalıştırma bitini geri getiremez, çünkü eşleşecek hiçbir şey kalmamıştır. O biti chmod u+x <file> ile geri yükleyin.
chmod dosyanın sahibini değiştirir mi?
Hayır. chmod yalnızca izin bitlerini değiştirir. Sahiplik, kullanıcı için chown ve grup için chgrp tarafından belirlenir; bir dosyayı başka bir kullanıcıya devretmek için root yetkisi gerekir. Bu önemlidir çünkü bitler, dosyayı en son kimin yazdığına göre değil, dosya üzerinde kayıtlı olan sahip ve gruba göre okunur. Hangi komuta ihtiyacınız olduğuna karar vermeden önce sahibi, grubu ve modu bir arada görmek için stat -c '%U %G %a %n' <file> çalıştırın.