Uso de disco por usuario en Linux / Unix

10

Necesito averiguar cuánto espacio en disco está ocupado por cada usuario en la red. Conozco dfy ducomandos: podría enumerar todo el sistema de archivos y AWK la salida, pero me pregunto si hay un comando más estándar.

El resultado que estoy buscando es:

usr1  xMb
usr2  yMb
[...]
Total zMb

¿Algunas ideas?

¡Gracias!

PD. Red Hat Linux EE

Escualo
fuente

Respuestas:

11

¿Es una cosa de una sola vez, o es esta información que desea poder extraer regularmente? En caso de que sea más tarde, una opción es aplicar cuotas en su sistema de archivos. Al hacerlo, el sistema realiza un seguimiento continuo de la cantidad de datos utilizados por cada usuario. De esa manera, la información es simplemente una consulta a la base de datos de cuotas.

andol
fuente
1
¡La cuota +1 es la solución!
ThorstenS
Una cosa de una sola vez; posiblemente una solución que puede almacenarse en un pequeño script para que los usuarios calculen su uso si lo desean. No podemos limitar la cantidad de datos debido a que el tipo de trabajo que hacemos no tiene en cuenta los límites estrictos.
Escualo
@ThorstenS: Hacemos cómputo técnico y necesitamos generar toneladas de información que pueden o no eliminarse después de realizar una ejecución. No creo que las cuotas ayuden en nuestra situación.
Escualo
1
@Arrieta: No tiene que limitar su uso. Simplemente dele a cada usuario una cuota ridículamente alta. Además, cada usuario puede consultar por sí mismo la base de datos de cuotas y ver cuántos datos están almacenando actualmente.
andol
2
Ni siquiera necesita establecer la cuota en un gran número, si la deja sin configurar (es decir, 0) no la impondrá, pero registrará el uso
Daniel
4

Otra buena solución que encontré aquí . Vaya al directorio de su interés, y ejecutar (como alternativa, el cambio .a cualquier directorio de intereses que, por ejemplo , /home/):

find . -type f -printf "%u  %s\n" \
  | awk '{user[$1]+=$2}; END{for(i in user) print i,user[i]}'
Jonas
fuente
1
+1. Tal vez agregue un tipo f ¿realmente solo está buscando archivos?
Hennes
Buena respuesta. Use -printf "%u\t%s\n"y awk -v OFS="\t"si cree que alguna vez podría tener un nombre de usuario con espacio.
TheDudeAbides
3

O para encontrar los usuarios problemáticos (directorios también),

du -xk | sort -n | tail -25

y para Solaris:

du -dk | sort -n | tail -25   

Esto le da una lista de los 25 directorios más grandes. No es exactamente lo que pediste, pero lo uso todo el tiempo.

Ronald Pottol
fuente
2

Lo que hacemos en muchos lugares es usar el sistema de cuotas, pero establecer cuotas absurdamente altas. De esta manera, obtiene el beneficio de informes rápidos. En un sitio, cada usuario tiene 1 TB de espacio de "cuota".

Periódicamente aumentamos la cuota a medida que crece el disco reparable: inicialmente era de 30 GB por usuario, algo que era absurdamente alto en ese momento.

David Mackintosh
fuente
0

No hay tal comando. Tienes que escribir algunos comandos de shell para esto.

  1. obtener todos los usuarios de / etc / passwd con uid> 1000
  2. use find -uid y busque todos los archivos del usuario
  3. usa esta lista para alimentar a du -s
ThorstenS
fuente
Ineficiente. No necesita ejecutar find varias veces si registra la información al mismo tiempo. Guarde esa información durante su primera ejecución. Ya sea en un archivo o en una matriz asociativa.
Hennes
0

El método de ThorstenS me parece que se necesita más trabajo, ya que se ejecuta find varias veces. Por un lado, solo haría 1 comando de búsqueda, y generaría el propietario y el tamaño de cada archivo, y luego haría algún tipo de magia en ese archivo.

La búsqueda sería algo así como que devuelve el nombre de usuario (o el número de identificación sin nombre de usuario) y el espacio utilizado en bytes, en un archivo delimitado por bytes nulos:

sudo bash -c 'find . -printf "%u\0%s\0" > username_usage'

Puede reemplazarlo \0con algo que podría ser un poco más fácil de trabajar, como pestañas o líneas nuevas, pero eso sería menos seguro si tiene nombres de archivo originales.

Si quisieras ser aún más eficiente, podrías canalizar la salida al script que lo maneja mientras se ejecuta, pero eso sería un poco más de trabajo, y tendrías que hacerlo bien la primera vez.

Kyle Brandt
fuente
0

Lo he logrado :) No rápido, pero funciona:

#!/bin/bash

# Displays disk usage per user in the specified directory
# Usage: ./scriptname [target-directory]

[ "x$1" == "x" ] && dirname="." || dirname="$1"
for uid in `cat /etc/passwd |awk -F : '{ print $1 }' ` ; do # List all usernames
    user_size=0
    for file in `find "$dirname" -type f -user "$uid" 2>/dev/null` ; do # List the folder's files that belongs to the current user, Ignore possible `find` errors.
        let user_size+=`stat -c '%s' $file` # Sum-up
        done
    [ $user_size -gt 0 ] && echo "USER=$uid, SIZE=$user_size" # Display the result if >0
    done

Se producirá un gran aumento de la velocidad si buscamos solo UID que sean> 1000:

- for uid in `cat /etc/passwd | sed -rn "s~^([^:]+):.*$~\1~p"` ; do # List all usernames
+ for uid in `cat /etc/passwd | sed -rn "s~^([^:]+):[^:]:[0-9]{4,}:.*$~\1~p"` ; do # List all usernames having UID>1000
Kolypto
fuente