SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor

chmod 755 o u+x: modalità numeriche e simboliche

Scopri chmod 755 e u+x, la differenza tra numeri ottali e forma u/g/o, perché chmod -R rompe un albero e quando usare X maiuscola.

Cosa modifica chmod

chmod modifica i bit dei permessi di un file o di una directory e accetta questi bit in una delle due notazioni disponibili. La forma numerica è un numero ottale che sostituisce tutti i bit dei permessi in una sola volta. La forma simbolica indica una classe di utenti e un operatore e modifica soltanto i bit specificati. Entrambe le forme terminano nella stessa chiamata di sistema. La differenza riguarda i bit non specificati.

Leggere una modalità e modificarla sono operazioni diverse. Se le lettere di un elenco lungo non sono ancora familiari, leggi prima cosa significa drwxr-xr-x campo per campo. Questa guida modifica soltanto questi bit.

Esegui tutti i comandi qui descritti con il normale utente di accesso. L'account root bypassa questi controlli, quindi una dimostrazione dei permessi eseguita come root non dimostra nulla. Se stai ancora lavorando come root su un nuovo server, crea un utente normale con privilegi minimi e poi torna qui.

Configura una sandbox eliminabile

cd "$(mktemp -d)"
touch notes.txt

mktemp -d crea una directory vuota sotto /tmp e stampa il percorso creato; la sostituzione di comando passa direttamente quel percorso a cd. Nessuno dei comandi seguenti modifica file che vuoi conservare.

Un comando mostra il risultato di ogni modifica:

stat -c '%a %A %n' notes.txt

%a stampa la modalità come numero ottale, %A stampa la stessa modalità nella forma a lettere usata da un elenco lungo e %n stampa il nome. Nei blocchi seguenti, una riga che inizia con $ è il comando da digitare; la riga sottostante è l'output prodotto dal comando. Esegui personalmente i comandi. L'output del tuo sistema dovrebbe corrispondere riga per riga, perché una modalità numerica non dipende da alcun elemento dell'ambiente.

La forma numerica: una cifra ottale per ogni classe

La prima cifra appartiene al proprietario del file. La seconda appartiene al gruppo del file. La terza appartiene a tutti gli altri utenti. Ogni cifra è una somma, con un valore per ogni bit. Imposta un bit alla volta e osserva cosa riporta stat.

$ 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.txt

Le lettere corrispondono alle cifre. Dopo il carattere iniziale che indica il tipo di file, il primo gruppo di tre lettere è quello del proprietario, il successivo è quello del gruppo e l'ultimo appartiene a tutti gli altri utenti. Somma i valori per combinare i bit all'interno di una classe.

$ 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.txt

Una modalità numerica è assoluta. A ogni esecuzione scrive tutti e nove i bit, quindi viene scritto anche lo stato di una classe a cui non avevi pensato.

$ 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

Il secondo comando non specificava nulla sul gruppo né sugli altri utenti, ma i relativi bit sono comunque cambiati. Questo è il comportamento della forma numerica e il motivo per cui la forma numerica non è lo strumento corretto per una modifica circoscritta. (chmod gestisce anche i bit setuid, setgid e sticky, che si trovano in una quarta cifra prima di queste. È un argomento distinto e questa guida tratta solo le tre cifre.)

La forma simbolica: una classe, un operatore, quindi i bit

Indicate prima la classe. u è il proprietario, g è il gruppo, o sono tutti gli altri utenti e a indica tutte le classi insieme. Poi indicate l'operatore: + aggiunge bit, - rimuove bit e = imposta la classe esattamente sui bit indicati, azzerando gli altri bit della classe. Infine indicate i bit, come r, w o 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.txt

Ogni comando modificava una sola classe e lasciava inalterate le altre. Separate le clausole con virgole, senza spazi: chmod le applica da sinistra a destra.

$ 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.txt

go=, senza nulla dopo il segno di uguale, rimuove tutti i bit dal gruppo e da tutti gli altri utenti. Questa è l'impostazione da usare per un file che può essere letto soltanto dal proprietario, ad esempio la parte privata di una coppia di chiavi SSH.

chmod può anche mostrare le modifiche eseguite. Questo è utile in uno script, quando nessuno controlla lo schermo.

chmod -v u+x notes.txt
chmod -v u+x notes.txt

-v stampa una riga per ogni file passato come argomento. Eseguite entrambi i comandi e confrontate le due righe visualizzate: la prima indica il file e riporta la modalità precedente e quella nuova, mentre la seconda segnala che la modalità è rimasta invariata, perché il bit da aggiungere era già impostato. -c stampa una riga soltanto quando un file viene effettivamente modificato, quindi è l'opzione più adatta da mantenere in un log.

chmod 755 rispetto a u+x: quale notazione usare

Parti dallo stesso file due volte e confronta ciò che ciascuna notazione lascia invariato.

$ 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.txt

Entrambi i comandi hanno reso il file eseguibile per il proprietario. Solo uno dei due ha lasciato inalterate le altre due classi. Usa una modalità numerica quando conosci lo stato finale esatto che vuoi ottenere e vuoi imporlo. Questo è il caso tipico di uno script di deployment che deve produrre lo stesso risultato su una macchina che non hai mai visto. Usa una modalità simbolica quando la frase che hai in mente contiene aggiungi o rimuovi, perché la forma numerica non consente di dire lascia invariata quella parte.

La modalità con cui parte un file nuovo non dipende affatto da chmod. Dipende da umask, cioè dalla maschera del processo che ha creato il file. Esegui umask e umask -S nella tua shell per visualizzare il valore attivo in quel contesto. Il valore può differire tra distribuzioni, tra la shell di login e un servizio systemd, nonché tra un account e un altro. umask imposta la modalità di ogni nuovo file, quindi determina lo stato di partenza prima dell'esecuzione di chmod.

Cosa fa il bit di esecuzione su una directory

Questo è l'equivoco che fa perdere più tempo. In un file normale, il bit di esecuzione indica al kernel che il file può essere eseguito. Una directory non contiene istruzioni, quindi non c'è nulla da eseguire al suo interno. Su una directory, il bit di esecuzione indica l'attraversamento: il permesso di risolvere un nome al suo interno. Per raggiungere dir/file, è necessario disporre di questo permesso su dir. Il bit di lettura è un permesso distinto e consente di elencare i nomi contenuti nella directory. È possibile avere uno dei due permessi senza l'altro, cosa più facile da capire dopo averlo verificato direttamente.

$ mkdir vault
$ printf 'hello\n' > vault/secret.txt
$ chmod 600 vault/secret.txt
$ chmod 100 vault
$ echo vault/*
vault/*
$ cat vault/secret.txt
hello

La shell ha ristampato il pattern senza modificarlo perché l'espansione di vault/* richiede la lettura della directory e un glob senza corrispondenze viene passato come testo letterale invece di generare un errore. cat ha comunque funzionato perché hai fornito direttamente il nome e l'attraversamento era consentito. Ora scambia i due bit.

$ chmod 400 vault
$ echo vault/*
vault/secret.txt
$ cat vault/secret.txt
cat: vault/secret.txt: Permission denied

I nomi sono visibili, ma i contenuti non lo sono. Il permesso di lettura fornisce l'elenco. Il permesso di esecuzione fornisce l'accesso. Quasi tutte le directory utilizzate richiedono entrambi.

$ chmod 500 vault
$ cat vault/secret.txt
hello

Perché chmod -R con una modalità numerica danneggia una struttura di directory

-R attraversa l’intera struttura e applica la modalità indicata a ogni elemento trovato. Una directory e un file di dati richiedono bit diversi, quindi un unico numero assoluto non può essere corretto per entrambi. Crea una struttura semplice e osserva l’errore.

$ 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.sh

Questa è la struttura che serve a una directory contenente file statici. Ecco il primo errore ricorsivo.

$ 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.css

Non si è verificato alcun errore, ed è proprio questo il problema. L’errore è silenzioso e rimane per anni nelle istruzioni copiate. Ora due file di dati risultano essere programmi. Git memorizza il bit di esecuzione, quindi il commit successivo trasferisce la modifica a tutti coloro che clonano il repository, mentre rsync e tar la trasferiscono a ogni macchina su cui copi la struttura.

Il secondo errore ricorsivo è evidente. Applica a una directory una modalità priva del bit di esecuzione e la directory non sarà più attraversabile.

$ 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 denied

I nomi vengono ancora elencati perché il bit di lettura è rimasto attivo, ma ogni percorso attraverso la directory è chiuso perché il bit di esecuzione non è più attivo. chmod -R 644 site applica questo cambiamento a tutte le directory della struttura con un solo comando. Il risultato non è sempre uniforme, perché chmod deve attraversare le stesse directory di cui sta rimuovendo il permesso di attraversamento. Controlla quindi ciò che è stato effettivamente applicato con find site -type d -exec stat -c '%a %n' {} +, senza dare per scontato il risultato. Ripristina questa modifica prima di continuare.

$ 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.html

Un chmod ricorsivo non dispone di una funzione di annullamento. chmod non registra ciò che ha sostituito, quindi la correzione consiste nel ricostruire manualmente le modalità che ritieni fossero presenti in precedenza. È lo stesso lavoro lento e incerto necessario per ricostruire i file dopo un rm -rf accidentale, e la lezione è la stessa: controlla il percorso di destinazione di un comando ricorsivo prima di premere Invio.

La X maiuscola: esecuzione sulle directory, non su ogni file

Le modalità simboliche accettano sia X sia x. X imposta il bit di esecuzione solo dove è appropriato: su una directory oppure su un file regolare che possiede già un bit di esecuzione per una delle classi. Questa regola corrisponde esattamente a quella che volevi far seguire a -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.sh

Un solo comando, e le directory sono rimaste attraversabili mentre i file di dati non sono stati modificati. Lo script ha mantenuto il proprio bit di esecuzione perché lo possedeva già: questa è la seconda parte della regola X. X legge la modalità attuale di un file, quindi un file che ha già perso tutti i bit di esecuzione non può recuperarli tramite questo comando.

$ 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
hi

La stessa regola funziona anche nel senso opposto. X estende a un'altra classe un bit di esecuzione già presente su un file:

$ chmod go+X site/deploy.sh
$ stat -c '%a %A %n' site/deploy.sh
755 -rwxr-xr-x site/deploy.sh

La x minuscola serve quindi per rendere eseguibile un singolo file specifico, mentre X serve per applicare la regola a un intero albero di directory. Quando vuoi assegnare una modalità esatta in base al tipo di elemento, invece di applicare una regola basata sulla modalità attuale, puoi separare la ricerca usando find.

find site -type d -exec chmod 755 {} +
find site -type f -exec chmod 644 {} +
chmod u+x site/deploy.sh

-type d seleziona le directory e -type f seleziona i file regolari, quindi ogni tipo riceve la modalità appropriata. -exec ... + raggruppa molti percorsi in una singola chiamata a chmod, invece di avviare un processo per ogni file. Questo è importante in un albero con migliaia di elementi. Lo script recupera il proprio bit su una riga separata, intenzionalmente.

Verifica il risultato prima di terminare

Due comandi individuano gli errori rilevanti dopo qualsiasi modifica ricorsiva. Il primo elenca le directory in cui non è più possibile accedere.

find . -type d ! -perm -u+x

Il secondo elenca i file che qualsiasi account del sistema può modificare.

find . -type f -perm -o+w

In -perm -o+w, il prefisso - significa almeno questi bit, quindi il comando corrisponde a un file la cui classe o contiene il bit di scrittura, indipendentemente dagli altri bit impostati. Il risultato desiderato è che nessuno dei due comandi visualizzi alcun elemento. Eseguili dalla directory principale di ogni struttura appena modificata con -R, quindi esegui stat -c '%a %A %n' sui pochi percorsi che intendevi modificare, per verificare che la modalità impostata corrisponda a quella effettivamente memorizzata dal kernel.

FAQ

Qual è la differenza tra chmod 755 e chmod u+x?

Una modalità numerica è assoluta. Scrive ogni bit di autorizzazione sul file, quindi riscrive anche le classi a cui non avevi pensato. Una modalità simbolica modifica lo stato esistente. u+x aggiunge un bit per il proprietario e lascia invariati tutti gli altri bit. Usa la forma numerica quando conosci lo stato finale esatto che vuoi ottenere su un file. Usa la forma simbolica quando vuoi aggiungere o rimuovere una singola autorizzazione. Esegui stat -c '%a %A %n' <file> prima e dopo entrambi i comandi: la differenza sarà visibile nell'output.

Perché chmod -R 755 su una directory contenente file web è una scelta errata?

Perché -R applica la stessa modalità assoluta alle directory e ai file regolari, ma questi due tipi richiedono bit diversi. Una directory ha bisogno del bit di esecuzione per poter essere attraversata. I file di dati, come HTML e CSS, non ne hanno bisogno; contrassegnarli come eseguibili è una modifica che git registra nel commit successivo e che rsync copia sulla macchina successiva. Usa chmod -R u=rwX,go=rX <dir> in modo che il bit di esecuzione venga applicato soltanto alle directory, oppure usa find con -type d e -type f, così ogni tipo riceve la propria modalità.

Che cosa fa il bit di esecuzione su una directory?

Consente l'attraversamento, non l'esecuzione. In una directory non c'è nulla da eseguire. Il bit di esecuzione autorizza la risoluzione di un nome al suo interno, quindi deve essere impostato su ogni directory lungo un percorso prima di poter aprire il file alla fine di quel percorso. Il bit di lettura è separato e consente di elencare i nomi. Puoi avere uno senza l'altro: con il solo bit di esecuzione puoi aprire un file di cui conosci già il nome, mentre la shell non può espandere un glob in quella directory; con il solo bit di lettura puoi vedere i nomi, ma ogni tentativo di aprirne uno fallisce.

Quando devo usare la X maiuscola invece della x minuscola?

Usa X ogni volta che il comando è ricorsivo. X imposta il bit di esecuzione sulle directory e sui file regolari soltanto quando almeno un bit di esecuzione è già impostato; in questo modo, una singola passata rende attraversabile un albero di directory senza trasformare i file di dati in programmi. Usa la x minuscola quando indichi un singolo file e intendi modificare proprio quel file. È importante ricordare un limite: X non può ripristinare un bit di esecuzione già rimosso da ogni file, perché non rimane alcun bit da usare come corrispondenza. Ripristinalo con chmod u+x <file>.

chmod modifica il proprietario di un file?

No. chmod modifica soltanto i bit di autorizzazione. La proprietà appartiene a chown per l'utente e a chgrp per il gruppo; assegnare un file a un utente diverso richiede root. Questo è importante perché i bit vengono interpretati rispetto all'utente e al gruppo registrati sul file, non rispetto a chi lo ha scritto per ultimo. Esegui stat -c '%U %G %a %n' <file> per visualizzare insieme proprietario, gruppo e modalità prima di decidere quale dei tre comandi ti serve effettivamente.