Soluzione 1:
Non aspettarti che funzioni velocemente...
cd in una directory in cui sospetti che possa esserci una sottodirectory con molti inode. Se questo script richiede un'enorme quantità di tempo, probabilmente hai trovato dove cercare nel filesystem. /var è un buon inizio...
Altrimenti, se passi alla directory superiore in quel filesystem e lo esegui e aspetti che finisca, troverai la directory con tutti gli inode.
find . -type d |
while
read line
do
echo "$( find "$line" -maxdepth 1 | wc -l) $line"
done |
sort -rn | less
Non sono preoccupato per il costo dello smistamento. Ho eseguito un test e l'ordinamento dell'output non ordinato rispetto a 350.000 directory ha richiesto 8 secondi. La scoperta iniziale ha richiesto . Il costo reale è l'apertura di tutte queste directory nel ciclo while. (il ciclo stesso richiede 22 secondi). (I dati del test sono stati eseguiti su una sottodirectory con 350.000 directory, una delle quali aveva un milione di file, il resto aveva tra 1 e 15 directory).
Varie persone hanno sottolineato che ls non è eccezionale in questo perché ordina l'output. Avevo provato l'eco, ma anche questo non è eccezionale. Qualcun altro aveva sottolineato che stat fornisce queste informazioni (numero di voci di directory) ma che non è portatile. Si scopre che find -maxdepth è molto veloce nell'aprire le directory e conta i file .file, quindi... eccolo... punti per tutti!
Soluzione 2:
Se il problema è una directory con troppi file, ecco una semplice soluzione:
# Let's find which partition is out of inodes:
$ df -hi
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda3 2.4M 2.4M 0 100% /
...
# Okay, now we know the mount point with no free inodes,
# let's find a directory with too many files:
$ find / -xdev -size +100k -type d
L'idea alla base del find
linea è che la dimensione di una directory è proporzionale alla quantità di file direttamente all'interno di quella directory. Quindi, qui cerchiamo directory con tonnellate di file al suo interno.
Se non vuoi indovinare un numero e preferisci elencare tutte le directory sospette ordinate per "dimensione", anche questo è facile:
# Remove the "sort" command if you want incremental output
find / -xdev -size +10k -type d -printf '%s %p\n' | sort -n
Soluzione 3:
Grrr, commentare richiede 50 ripetizioni. Quindi questa risposta è in realtà un commento sulla risposta di Chris.
Dal momento che l'interrogante probabilmente non si preoccupa di tutte le directory, solo di quelle peggiori, l'uso di sort è probabilmente un'esagerazione molto costosa.
find . -type d |
while
read line
do
echo "$(ls "$line" | wc -l) $line"
done |
perl -a -ne'next unless $F[0]>=$max; print; $max=$F[0]' | less
Questa non è completa come la tua versione, ma ciò che fa è stampare le linee se sono più grandi del massimo precedente, riducendo notevolmente la quantità di rumore stampato e risparmiando la spesa dell'ordinamento.
Lo svantaggio è che se hai 2 directory molto grandi e la prima ha 1 inode in più rispetto alla seconda, non vedrai mai la seconda.
Una soluzione più completa sarebbe quella di scrivere uno script perl più intelligente che tenga traccia dei primi 10 valori visualizzati e li stampi alla fine. Ma è troppo lungo per una rapida risposta serverfault.
Inoltre, alcuni script perl mediamente più intelligenti ti permetterebbero di saltare il ciclo while:sulla maggior parte delle piattaforme, ls ordina i risultati e questo può anche essere molto costoso per directory di grandi dimensioni. L'ordinamento ls non è necessario qui, poiché tutto ciò che ci interessa è il conteggio.
Soluzione 4:
Puoi usare questo piccolo frammento:
find | cut -d/ -f2 | uniq -c | sort -n
Stamperà quanti file e directory si trovano in ciascuna delle directory nella cartella corrente, con i trasgressori più grandi in fondo. Ti aiuterà a trovare directory che contengono molti file. (ulteriori informazioni)
Soluzione 5:
Questa non è una risposta diretta alla tua domanda, ma la ricerca di file modificati di recente con dimensioni ridotte utilizzando find potrebbe restringere la ricerca:
find / -mmin -10 -size -20k