
Ich muss die von jedem Benutzer auf meinem Linux-Server belegte Größe überprüfen (alle Dateien rekursiv in meinem Datenordner).
Mit dem folgenden Code kann ich alle meine Dateien und ihre Benutzer abrufen, aber ich weiß nicht, wie ich sie anschließend gruppieren und summieren kann.
#> find . -type f -ls | sort -k5
Hat jemand eine Idee, um dieses Problem zu lösen?
Antwort1
Mit GNU find
:
find . -printf '%D+%i:%u:%b\n' | awk -F: '
!seen[$1]++ {du[$2] += $3}
END {for (user in du) printf "%20s: %lu\n", user, du[user] * 512}'
Dadurch wird die Festplattennutzung in Byte für jeden Benutzer gemeldet. Dabei du
wird darauf geachtet, dass Hardlinks nicht mehrfach gezählt werden.
find
druckt für jede Datei die Geräte- und Inode-Nummer ( %D+%i
) (bei Hardlinks auf die gleiche Datei wären sie identisch), den Benutzernamen und die Festplattennutzung in Einheiten von 512 Byte.
:
wird als Feldtrennzeichen verwendet, da Benutzernamen diese normalerweise nicht enthalten, weil sie das Feldtrennzeichen in der Benutzerdatenbank sind (wie /etc/passwd
oder die Ausgabe von getent passwd
).
Diese Liste wird an weitergeleitet awk
, wo wir für jede Datei, für die das erste Feld noch nicht indiziert wurde, ein du
assoziatives Array aktualisieren, das auf den Namen des Benutzers (das zweite Feld) indiziert ist .$2
seen
Am END
durchlaufen wir die Elemente des assoziativen Arrays, um die kumulierte Festplattennutzung für jeden Benutzer zu ermitteln (durch Multiplikation der Anzahl derBlöckeum die Informationen in Bytes zu erhalten).
Antwort2
Das sollte funktionieren. Es ist etwas langsam und verwendet alle Benutzer in Ihrem /etc/passwd, aber das lässt sich leicht ändern und ich bin mir nicht sicher, welche Art von Benutzern Sie haben ( lastlog
würde wahrscheinlich auch funktionieren)
Beachten Sie, dass hierbei das aktuelle Arbeitsverzeichnis verwendet wird (siehe find .
).
Der Oneliner:
for user in $(cut -d: -f1 < /etc/passwd); do echo -en "$user has:\t"; find . -user $user -type f -print0 | du --files0-from=- --total -sh | tail -n1 ; done
Hier ist das Gleiche, aber etwas ausführlicher:
# Read all lines in /etc/password, use ":" as field separator and print first field
for user in $(cut -d: -f1 < /etc/passwd); do
# Print username, -e to allow \t, -n to skip newline
echo -en "$user is using:\t"
# Find all files owned by $user, print found files to stdout and terminate
# with a null character (thus circumventing the long file list problem).
# let `du` read from null terminated stdin usint --files0-from=-, make a total,
# make a summary and make it human readable, then only print the last line
# containing the total
find . -user "$user" -type f -print0 | du --files0-from=- --total -sh | tail -n1
done
Antwort3
Berechnen des von den Dateien jedes Benutzers belegten Speicherplatzes
Dieses bash
Shellskript verwendet
find
um die Besitzer zu finden- eine
for
Schleife mit einerfind
Befehlszeile, um alle Dateien zu finden, die jedem Besitzer gehören- und leiten Sie die Dateinamen weiter an
du
- und leiten Sie die Dateinamen weiter an
- nachdem
du
das Ergebnis nachbearbeitet wurde, um es leichter lesbar zu machen.
Das Shellskript ist ziemlich schnell, wenn es in Partitionen mit vielen Dateien getestet wird.
#!/bin/bash
# store owners in variable
user=$(whoami)
if [ "$user" != "root" ]
then
echo "Run with elevated permissions (as root or with sudo)"
exit
elif ! test -d "$1"
then
echo "Enter a target directory as parameter"
exit
fi
owners=$(find "$1" -printf "%u\n"|sort | uniq)
#echo "$owners"
leng=0
for i in $owners
do
if [ ${#i} -gt $leng ]
then
leng=${#i}
fi
done
#echo "$leng"
skip=$((leng - 4))
spc=$(for ((i=0;i<skip;i++)); do printf " "; done)
printf "User $spc Size\n---- $spc ----\n"
for i in $owners
do
skip=$((leng - ${#i}))
spc=$(for ((i=0;i<skip;i++)); do printf " "; done)
printf "$i $spc "
find "$1" -type f -user "$i" -print0 | du --files0-from=- --total -sh |
tail -n1 | cut -f 1
done
Demobeispiele
Den Namen annehmendisk-usage-by-owner
ubuntu@ubuntu:~$ ./disk-usage-by-owner
Run with elevated permissions (as root or with sudo)
ubuntu@ubuntu:~$ sudo ./disk-usage-by-owner
Enter a target directory as parameter
Dialog im permanenten Live-Drive
ubuntu@ubuntu:~/bin$ sudo ./disk-usage-by-owner /cdrom
User Size
---- ----
root 1.9G
ubuntu@ubuntu:~/bin$ sudo ./disk-usage-by-owner /home
User Size
---- ----
root 0
ubuntu 1.9G
ubuntu@ubuntu:~/bin$ sudo ./disk-usage-by-owner /media/ubuntu/casper-rw
User Size
---- ----
_apt 0
colord 44K
gdm 288K
man 628K
root 1007M
syslog 127M
systemd-timesync 0
ubuntu 1.9G
Hardlinks werden nur einmal gezählt
$ sudo find . -user root -ls
56492055 1024 -rw-r--r-- 3 root root 1048576 jan 16 23:41 ./owned\ by\ root\ hard-linked
56492055 1024 -rw-r--r-- 3 root root 1048576 jan 16 23:41 ./owned\ by\ root
56492055 1024 -rw-r--r-- 3 root root 1048576 jan 16 23:41 ./sub/owned\ by\ root
$ sudo ./disk-usage-by-owner .
User Size
---- ----
root 1,0M
sudodus 32K
$ du .
4 ./sub
1064 .
Antwort4
Dies geht möglicherweise etwas schneller, wenn Sie über die richtigen Versionen von find, stat und awk verfügen:
find . -type f -exec stat -c "%U %s" {} \; | awk '{sum[$1]+=$2} END {for (u in sum) {printf("%s: %d\n", u, sum[u])}}'
Dadurch wird der Befehl stat(1) für alle Dateien ausgeführt, die vom Befehl find(1) gefunden wurden. stat gibt den Benutzernamen und die Größe der Datei aus. Dies wird dann an awk übergeben. Der Befehl awk summiert einfach alle Größen für einen bestimmten Benutzer für alle Dateien. Sobald alle Dateien verarbeitet wurden, werden alle Benutzer ausgedruckt, die in der Summenliste enthalten sind, zusammen mit der Gesamtgröße aller Dateien für diesen Benutzer.