Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I need to find out how much disk space is being occupied by each user on the network. I am aware of df and du commands: I could list the entire filesystem and AWK the output, but I wonder if there is a more standard command.

The output I am looking for is:

usr1  xMb
usr2  yMb
[...]
Total zMb

Any ideas?

Thanks!

PS. Red Hat Linux EE

share|improve this question

7 Answers 7

Is this a one time thing, or is this information you want to be able to extract regularly? In case it is the later then one option is to apply quotas on your filesystem. Doing that the system continuously keeps track of the amount of data used by each user. That way the information is merely a query to the quota database away.

share|improve this answer
1  
+1 quota is the solution! –  ThorstenS Dec 15 '09 at 19:48
    
A one-time thing; possibly a solution which can be stored in a small script for the users to compute their usage if they want to. We cannot limit the amount of data because of the type of work we do does not accommodate hard limits. –  Escualo Dec 15 '09 at 19:49
    
@ThorstenS: We do technical computing and we need to generate tons of information which may or may not be removed after a run is made. I don't think quotas help in our situation. –  Escualo Dec 15 '09 at 19:50
1  
@Arrieta: You don't have to limit their usage. Simply give each user a ridiculously hight quota. Also, every user can by themselves query the quota database and see how much data they are currently storing. –  andol Dec 15 '09 at 20:00
2  
You don't even need to set the quota to a big number, if you leave it unset (i.e. 0) it will not enforce it, but it will record the usage –  Daniel Dec 15 '09 at 21:36

What we do in many places is use the quota system, but set absurdly high quotas. This way you get the benefit of fast reporting. At one site, each user has 1 TB of "quota" space.

We periodically bump the quota higher as serviceable disk grows -- initially it was 30GB per user, something that was absurdly high at the time.

share|improve this answer

Or for finding the problem users (directories too),

du -xk | sort -n | tail -25

and for Solaris:

du -dk | sort -n | tail -25   

This gives you a list of the 25 largest directories. Not quite what you asked for, but I use it all the time.

share|improve this answer

Another nice solution I found here. Navigate to the directory of interest, and run (altneratively, change . to whichever directory interestes you, e.g. /home/):

find . -printf "%u  %s\n" | awk '{user[$1]+=$2}; END{ for( i in user) print i " " user[i]}'
share|improve this answer
    
+1. Maybe add a -type f is you are really only looking for files? –  Hennes Aug 22 at 18:37

There ist no such command. You have to write some shell commands for this.

  1. get all users from /etc/passwd with uid >1000
  2. use find -uid and search all files of the user
  3. use this list to feed du -s
share|improve this answer
    
Inefficient. You do not need to run find several times if you log the information in the same time. Save that information during your first run. Either in a file, or in an associative array. –  Hennes Aug 22 at 18:35

ThorstenS's method seems like more work then is needed to me because it runs find multiple times. For a one off, I would just do 1 find command, and output the owner and size of each file, and then do some sort magic on that file.

The find would be something like which returns username (or id number of no username) and space used in bytes, in a null-byte delimited file:

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

You can replace the \0 with something that might be a little bit easier to work with, like tabs or newlines, but that would be less safe if you have funky file names.

If you wanted to be even more efficient, you could pipe the output to script that handles it as it runs, but that would be a little more work, and you would have to get it right the first time.

share|improve this answer

I've made it :) Not fast thou, but works:

#!/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

Great speed increase will occur if we seek only for UIDs that are >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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.