chmod numeriek of symbolisch: wat is het verschil?
Leer het verschil tussen chmod 755 en u+x. Ontdek waarom een recursieve numerieke modus mappen beschadigt en hoe de hoofdletter X dit probleem in Linux definitief oplost.
Wat chmod wijzigt
chmod wijzigt de permissiebits van een bestand of map en accepteert deze bits in een van de twee notaties. De numerieke vorm is een octaal getal dat alle permissiebits tegelijk vervangt. De symbolische vorm benoemt een gebruikersklasse en een operator, en wijzigt alleen de bits die u opgeeft. Beide eindigen in dezelfde systeemaanroep. Het verschil zit in wat er gebeurt met de bits die u niet noemt.
Het lezen van een modus en het wijzigen van een modus zijn verschillende taken. Als de letters in een lange lijst nog niet duidelijk zijn, lees dan eerst wat drwxr-xr-x veld voor veld betekent. Deze handleiding wijzigt ze alleen.
Voer alles hier uit als uw normale inloggebruiker. Het root-account omzeilt deze controles, dus een demonstratie van permissies uitgevoerd als root bewijst niets. Als u nog steeds als root op een nieuwe server werkt, maak dan een normale gebruiker met minimale rechten aan en kom daarna terug.
Een tijdelijke sandbox opzetten
cd "$(mktemp -d)"
touch notes.txtmktemp -d maakt een lege map aan onder /tmp en toont het aangemaakte pad, waarna command substitution dat pad direct doorgeeft aan cd. Niets hieronder heeft invloed op bestanden die voor u van belang zijn.
Eén commando rapporteert het resultaat van elke wijziging:
stat -c '%a %A %n' notes.txt%a toont de modus als een octaal getal, %A toont dezelfde modus in de lettervorm die een lange lijstweergave gebruikt, en %n toont de naam. In de onderstaande blokken is een regel die begint met $ wat u typt, en de regel daaronder is wat het commando heeft uitgevoerd. Voer ze zelf uit. De uitvoer op uw machine moet regel voor regel overeenkomen, omdat een numerieke modus niet afhankelijk is van uw omgeving.
De numerieke vorm: één octaal cijfer per klasse
Het eerste cijfer hoort bij de eigenaar van het bestand. Het tweede hoort bij de groep van het bestand. Het derde hoort bij alle anderen. Elk cijfer is een som, één waarde per bit. Stel één bit tegelijk in en lees wat stat rapporteert.
$ 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.txtDe letters komen overeen met de cijfers. Na het eerste teken dat het bestandstype aangeeft, is de eerste groep van drie letters voor de eigenaar, de volgende drie voor de groep en de laatste drie voor alle anderen. Tel de waarden bij elkaar op om bits binnen één klasse te combineren.
$ 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.txtEen numerieke modus is absoluut. Deze schrijft alle negen bits bij elke uitvoering, dus een klasse waar u niet aan dacht, wordt ook overschreven.
$ 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.txtHet tweede commando zei niets over de groep of over alle anderen, en hun bits veranderden toch. Dat is het kenmerk van de numerieke vorm, en daarom is de numerieke vorm het verkeerde hulpmiddel voor een kleine aanpassing. (chmod verwerkt ook de setuid-, setgid- en sticky-bits, die in een vierde cijfer vóór deze drie staan. Dat is een apart onderwerp, en deze handleiding beperkt zich tot de drie.)
De symbolische vorm: een klasse, een operator, dan de bits
Schrijf eerst de klasse. u is de eigenaar, g is de groep, o is iedereen en a is allemaal tegelijk. Daarna de operator: + voegt bits toe, - verwijdert bits en = stelt die klasse exact in op de bits die u opgeeft en wist de rest van de bits. Vervolgens de bits zelf, als r, w of x.
$ 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.txtElk commando wijzigde één klasse en liet de andere ongemoeid. Combineer clausules met komma's zonder spaties, en chmod past ze van links naar rechts toe.
$ 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.txtgo= met niets na het gelijkteken verwijdert elke bit van de groep en van iedereen. Dat is de gewenste configuratie voor een bestand dat alleen door de eigenaar gelezen mag worden, zoals de private helft van een SSH-sleutelpaar.
chmod kan ook rapporteren wat het heeft gedaan, wat van belang is in een script waar niemand meekijkt op het scherm.
chmod -v u+x notes.txt
chmod -v u+x notes.txt-v print een regel voor elk bestand dat werd meegegeven. Voer beide commando's uit en vergelijk de twee regels op uw scherm: de eerste noemt het bestand en rapporteert de modus van vóór en na de wijziging, en de tweede rapporteert de modus als behouden, omdat de bit die moest worden toegevoegd al was ingesteld. -c print alleen een regel wanneer een bestand daadwerkelijk is gewijzigd, dus dit is de betere optie om in een logbestand op te nemen.
chmod 755 versus u+x: welke notatie te gebruiken
Begin tweemaal met hetzelfde bestand en vergelijk wat elke notatie achterlaat.
$ 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.txtBeide commando's maakten het bestand uitvoerbaar voor de eigenaar. Slechts één van beide liet de andere twee klassen ongewijzigd. Gebruik een numerieke modus wanneer u de exacte eindtoestand weet die u wilt bereiken en u deze wilt afdwingen; dit is de gebruikelijke situatie in een deployment-script dat op een onbekende machine hetzelfde resultaat moet opleveren. Gebruik een symbolische modus wanneer uw intentie toevoegen of verwijderen is, omdat de numerieke vorm geen manier heeft om aan te geven dat een specifiek deel ongewijzigd moet blijven.
De modus waarmee een nieuw bestand begint, komt niet voort uit chmod. Deze wordt bepaald door de umask van het proces dat het bestand heeft aangemaakt. Voer umask en umask -S uit in uw eigen shell om de actieve waarde te zien. Houd er rekening mee dat deze verschilt tussen distributies, tussen uw login-shell en een systemd-service, en tussen verschillende accounts. De umask stelt de modus van elk nieuw bestand in, dus deze bepaalt de uitgangssituatie voordat chmod wordt uitgevoerd.
Wat de execute-bit doet op een directory
Dit is het misverstand dat de meeste tijd kost. Bij een gewoon bestand betekent de execute-bit dat de kernel het bestand mag uitvoeren. Een directory bevat geen instructies, dus er valt niets in uit te voeren. Op een directory betekent de execute-bit traversal: toestemming om een naam daarbinnen op te lossen. Om dir/file te bereiken, heeft u deze bit nodig op dir. De read-bit is een afzonderlijke toestemming en staat toe dat de namen in de directory worden opgesomd. U kunt de ene bit hebben zonder de andere; dit is makkelijker te geloven zodra u het in de praktijk heeft gezien.
$ mkdir vault
$ printf 'hello\n' > vault/secret.txt
$ chmod 600 vault/secret.txt
$ chmod 100 vault
$ echo vault/*
vault/*
$ cat vault/secret.txt
helloDe shell gaf het patroon ongewijzigd terug omdat het uitbreiden van vault/* betekent dat de directory wordt gelezen, en een glob die niets matcht wordt doorgegeven als letterlijke tekst in plaats van een foutmelding te genereren. cat werkte nog steeds omdat u de naam zelf opgaf en traversal was toegestaan. Wissel nu de twee bits om.
$ chmod 400 vault
$ echo vault/*
vault/secret.txt
$ cat vault/secret.txt
cat: vault/secret.txt: Permission deniedDe namen zijn zichtbaar, maar de inhoud niet. Read geeft u de lijst. Execute geeft u de toegang. Bijna elke directory die u gebruikt, vereist beide.
$ chmod 500 vault
$ cat vault/secret.txt
helloWaarom chmod -R met een numerieke modus een mappenstructuur beschadigt
-R doorloopt de gehele mappenstructuur en past de opgegeven modus toe op alles wat het tegenkomt. Een map en een databestand vereisen verschillende bits; één absoluut getal kan daarom nooit voor beide correct zijn. Bouw een kleine mappenstructuur en zie hoe het misgaat.
$ 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.shDit is de indeling die een map met statische bestanden vereist. Hier is de eerste recursieve fout.
$ 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.cssEr ging niets kapot, en dat is precies het probleem. Deze fout is stil, waardoor deze jarenlang in gekopieerde instructies blijft voortbestaan. Twee databestanden claimen nu programma's te zijn. Git slaat de execute-bit op, dus uw volgende commit draagt de wijziging over aan iedereen die de repository kloont, en rsync en tar dragen deze over naar elke machine waarnaar u de mappenstructuur kopieert.
De tweede recursieve fout is luidruchtig. Richt een modus zonder execute-bit op een map en de map wordt ontoegankelijk.
$ 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 deniedDe namen worden nog steeds weergegeven omdat de read-bit behouden bleef, maar elk pad door de map is afgesloten omdat de execute-bit verdween. chmod -R 644 site doet dit met elke map in de structuur in één commando. Wat u daarna aantreft is niet altijd uniform, omdat chmod door dezelfde mappen moet lopen waarvan het de toegang zojuist heeft ingetrokken. Controleer daarom met find site -type d -exec stat -c '%a %n' {} + wat er daadwerkelijk is toegepast in plaats van ervan uit te gaan dat het klopt. Herstel dit voordat u verdergaat.
$ 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.htmlEen recursieve chmod heeft geen ongedaan-maakfunctie. chmod registreert niet wat het heeft vervangen, dus het herstel is aan u: u moet de modi opnieuw opbouwen op basis van wat u denkt dat ze waren. Dat is hetzelfde trage en onzekere werk als bestanden reconstrueren na een per ongeluk uitgevoerde rm -rf, en de les is dezelfde: controleer het doel van een recursief commando voordat u op enter drukt.
De hoofdletter X: uitvoeren op mappen, niet op elk bestand
Symbolische modi accepteren X evenals x. X stelt de uitvoer-bit alleen in waar dit logisch is: op een map, of op een regulier bestand dat al een uitvoer-bit heeft voor een bepaalde klasse. Die regel is precies de regel die u wilde dat -R zou volgen.
$ 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.shEén commando, en de mappen bleven toegankelijk terwijl de databestanden ongewijzigd bleven. Het script behield zijn uitvoer-bit omdat het er al een had, wat de tweede helft van de X-regel is. X leest de modus die een bestand op dit moment heeft, dus een bestand dat al elke uitvoer-bit is verloren, kan hiermee niet worden hersteld.
$ 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
hiDezelfde regel werkt ook andersom. X breidt een uitvoer-bit die een bestand al heeft uit naar een andere klasse:
$ chmod go+X site/deploy.sh
$ stat -c '%a %A %n' site/deploy.sh
755 -rwxr-xr-x site/deploy.shDus de kleine letter x is voor één specifiek bestand dat u uitvoerbaar wilt maken, en X is voor een actie over een hele boomstructuur. Wanneer u een exacte modus per type object wilt in plaats van een regel gebaseerd op de huidige modus, splitst u de actie met find.
find site -type d -exec chmod 755 {} +
find site -type f -exec chmod 644 {} +
chmod u+x site/deploy.sh-type d selecteert mappen en -type f selecteert reguliere bestanden, zodat elk type de modus krijgt die het hoort te hebben. -exec ... + groepeert vele paden in één chmod-aanroep in plaats van een proces per bestand te starten, wat van belang is bij een boomstructuur met duizenden items. Het script krijgt zijn bit terug op een aparte regel, bewust.
Controleer het resultaat voordat u verdergaat
Twee commando's sporen de fouten op die ertoe doen na een recursieve wijziging. Het eerste commando toont mappen die u niet langer kunt openen.
find . -type d ! -perm -u+xHet tweede commando toont bestanden die door elk account op de machine kunnen worden bewerkt.
find . -type f -perm -o+wIn -perm -o+w betekent de voorloop-- ten minste deze bits. Het komt dus overeen met een bestand waarvan de o-klasse het schrijfbit bevat, ongeacht welke andere bits zijn ingesteld. Het gewenste resultaat is dat geen van beide commando's uitvoer geeft. Voer beide commando's uit vanaf de bovenkant van elke boomstructuur die u zojuist heeft gewijzigd met -R, en voer stat -c '%a %A %n' uit op de handvol paden die u wilde wijzigen. Zo zorgt u ervoor dat de modus waarvan u denkt dat u deze heeft ingesteld, ook daadwerkelijk de modus is die de kernel hanteert.
FAQ
Wat is het verschil tussen chmod 755 en chmod u+x?
Een numerieke modus is absoluut. Deze schrijft elke permissiebit op het bestand, waardoor de klassen waar u niet aan dacht ook worden overschreven. Een symbolische modus is een aanpassing. u+x voegt één bit toe voor de eigenaar en laat elke andere bit ongewijzigd. Gebruik de numerieke vorm wanneer u de exacte eindtoestand van een bestand wilt vastleggen. Gebruik de symbolische vorm wanneer u één aspect wilt toevoegen of verwijderen. Voer stat -c '%a %A %n' <file> uit voor en na elk van beide commando's om het verschil in de uitvoer te zien.
Waarom is chmod -R 755 op een map met webbestanden een slecht idee?
Omdat -R dezelfde absolute modus toepast op zowel mappen als gewone bestanden, terwijl deze twee verschillende bits vereisen. Een map heeft de uitvoerbit (execute bit) nodig om toegankelijk te zijn. Databestanden zoals HTML en CSS hebben deze niet nodig; het markeren ervan als uitvoerbaar is een wijziging die git registreert in uw volgende commit en die rsync kopieert naar de volgende machine. Gebruik chmod -R u=rwX,go=rX <dir> zodat de uitvoerbit alleen op mappen wordt toegepast, of stuur dit aan vanuit find met -type d en -type f, zodat elk type zijn eigen modus krijgt.
Wat doet de uitvoerbit op een map?
Deze verleent toegang tot de map, niet tot uitvoering. Er is niets in een map dat uitgevoerd kan worden. De uitvoerbit is de toestemming om een naam binnen die map te resolven; u heeft deze dus nodig op elke map in een pad voordat u het bestand aan het einde van dat pad kunt openen. De leesbit is afzonderlijk en verleent het recht om de namen in de map te tonen. U kunt de ene zonder de andere hebben: met alleen de uitvoerbit kunt u een bestand openen waarvan u de naam al kent, terwijl de shell geen glob in die map kan uitbreiden. Met alleen de leesbit kunt u de namen zien, terwijl elke poging om een bestand te openen mislukt.
Wanneer moet ik de hoofdletter X gebruiken in plaats van de kleine letter x?
Gebruik X wanneer het commando recursief is. X stelt de uitvoerbit in op mappen, en op gewone bestanden alleen als er al een uitvoerbit is ingesteld. Hierdoor wordt een boomstructuur in één doorgang toegankelijk zonder databestanden in programma's te veranderen. Gebruik de kleine letter x wanneer u naar één specifiek bestand verwijst. Eén beperking is belangrijk om te onthouden: X kan een uitvoerbit die overal op een bestand is verwijderd niet herstellen, omdat er geen bit meer is om op te matchen. Herstel die bit met chmod u+x <file>.
Verandert chmod de eigenaar van een bestand?
Nee. chmod wijzigt alleen de permissiebits. Het eigendom behoort toe aan chown voor de gebruiker en chgrp voor de groep; voor het overdragen van een bestand aan een andere gebruiker is root nodig. Dit is van belang omdat de bits worden getoetst aan de eigenaar en groep die op het bestand zijn vastgelegd, niet aan degene die het bestand als laatste heeft geschreven. Voer stat -c '%U %G %a %n' <file> uit om de eigenaar, de groep en de modus samen te zien voordat u beslist welk van de drie commando's u daadwerkelijk nodig heeft.