472

I'm trying to write a script that will calculate a directory size and if the size is less than 10GB, and greater then 2GB do some action. Where do I need to mention my folder name?

# 10GB
SIZE="1074747474"

# check the current size
CHECK="`du /data/sflow_log/`"
if [ "$CHECK" -gt "$SIZE" ]; then
  echo "DONE"
fi
codeforester
  • 39,467
  • 16
  • 112
  • 140
tom
  • 5,114
  • 6
  • 24
  • 36
  • 1
    And if you want to sort it: http://serverfault.com/questions/62411/how-can-i-sort-du-h-output-by-size – cregox Nov 19 '15 at 14:06
  • Related questions: https://stackoverflow.com/q/1241801/5447906, https://unix.stackexchange.com/q/185764/152606 – anton_rh Sep 24 '18 at 13:51
  • Since this is a popular question - If any beginner is encountering the answers on this question and wants to learn more about what the heck `du` is and how everyone knows all these commands: You can type `man du` in your terminal to lookup the du command in the manual. This will display an output which you can view, and will summarize all the flags like -h, -c, -s, -b, -B, --apparent-size, etc. that answers are you suggesting you use. Then, you can decide for yourself how you best want to use `du` for your specific use case. – Josh Desmond Apr 12 '20 at 14:24

8 Answers8

885

You can do:

du -hs your_directory

which will give you a brief output of the size of your target directory. Using a wildcard like * can select multiple directories.

If you want a full listing of sizes for all files and sub-directories inside your target, you can do:

du -h your_directory

Tips:

  • Add the argument -c to see a Total line at the end. Example: du -hcs or du -hc.

  • Remove the argument -h to see the sizes in exact KiB instead of human-readable MiB or GiB formats. Example: du -s or du -cs.

ADTC
  • 8,999
  • 5
  • 68
  • 93
Mingyu
  • 31,751
  • 14
  • 55
  • 60
  • 25
    You don't want human-readable numbers when you're trying to get a value for a script. – paddy May 21 '13 at 04:17
  • 5
    With no directory path specified it will default to the current working directory. so `du -hs` == `du -hs .`. – razz Apr 20 '15 at 03:00
  • 16
    Also check out: `du | sort -n` it will sort the directories by its size – optimiertes Jan 28 '16 at 04:55
  • 8
    `du -hcs dir_name/*` includes the subfolders – optimiertes Aug 01 '16 at 20:40
  • 1
    du -h | tail -1 ? – Alexander Mills Dec 01 '16 at 11:00
  • For very large directories (like a ~TB drive), I find `du -hcs -t 5000` to be very useful. Speeds things up _significantly_ and doesn't really effect total size of large systems. – nivk Jun 11 '17 at 17:15
  • 1
    Use `du -s` for a summary (i.e. totals the size of all subdirectories) – Andrew Kirna Jun 20 '18 at 21:01
  • The default behaviour is not listing all files and directories. It only lists directories. Also, omitting the size option will cause `du` to use `BLOCKSIZE` which is usually 512 Byte rather than 1kB. – yzhang Mar 20 '22 at 12:15
  • 1
    `du -h --max-depth 1 . | sort -hr` summary of folders in current folder sorted from largest in human readable form – Bartosh Aug 14 '22 at 00:22
  • 1
    `sort -n` will sort numbers but is ignorant of unit. I.e. 987K will sort as though it's larger than 3MB. Also `--max-depth is not recognised, but `du -h -d 1 . | sort -h` will work. – matharden Sep 05 '22 at 13:58
177

if you just want to see the folder size and not the sub-folders, you can use:

du -hs /path/to/directory

Update:

You should know that du shows the used disk space; and not the file size.

You can use --apparent-size if u want to see sum of actual file sizes.

--apparent-size
      print  apparent  sizes,  rather  than  disk  usage; although the apparent size is usually smaller, it may be larger due to holes in ('sparse')
      files, internal fragmentation, indirect blocks, and the like

And of course theres no need for -h (Human readable) option inside a script.

Instead You can use -b for easier comparison inside script.

But You should Note that -b applies --apparent-size by itself. And it might not be what you need.

-b, --bytes
      equivalent to '--apparent-size --block-size=1'

so I think, you should use --block-size or -B

#!/bin/bash
SIZE=$(du -B 1 /path/to/directory | cut -f 1 -d "   ")    
# 2GB = 2147483648 bytes
# 10GB = 10737418240 bytes
if [[ $SIZE -gt 2147483648 && $SIZE -lt 10737418240 ]]; then
    echo 'Condition returned True'
fi
Bruce Sun
  • 631
  • 1
  • 10
  • 26
Taxellool
  • 4,063
  • 4
  • 21
  • 38
  • I know it's been a couple of years, but would you be so kind as to explain a little bit what is the purpose of regex and BASH_REMATCH in the conditionals? (or to provide some links as to the usage of those variables/commands/formats) I would have expected the code to just get the size of the file in a variable and compare that with 10 gb directly, what are those other things doing? – Nordico May 20 '16 at 14:07
  • 2
    @Nordico yup. there was no need for regex and BASH_REMATCH so I updated the answer. – Taxellool Jun 29 '16 at 07:54
  • I've found that using `-B 1` or `-B any-number` gives an inaccurate folder size in `KB` that's 2x bigger than expected. A more accurate way is to use `-k` , which uses 1024-byte blocks, and it gives a `kilobyte` output that closely matches the File Browser and also matches the `-h` (human readable) option. Also the cut command should be `cut -f 1` to work. – Mr-IDE Oct 28 '22 at 09:24
45

To check the size of all of the directories within a directory, you can use:

du -h --max-depth=1
Deepak Mahakale
  • 22,834
  • 10
  • 68
  • 88
Michael Silverstein
  • 1,653
  • 15
  • 17
  • 5
    On some systems, the `--max-depth=1` flag does not work with the `du` command. So you can instead use `-d1` for the same behavior. For example: `du -h -d2 "$HOME"` – Mr-IDE Oct 27 '22 at 10:36
40

Use a summary (-s) and bytes (-b). You can cut the first field of the summary with cut. Putting it all together:

CHECK=$(du -sb /data/sflow_log | cut -f1)
paddy
  • 60,864
  • 6
  • 61
  • 103
  • 4
    I am new to shell scripting. Output of du command included directory name. I was unable to get only number part. "cut" in your answer solved the mystery! – Kanad Aug 17 '18 at 15:34
39

To just get the size of the directory, nothing more:

du --max-depth=0 ./directory

output looks like

5234232       ./directory
siliconrockstar
  • 3,554
  • 36
  • 33
  • 9
    `--max-depth` is very useful for usefully controlling the output! for example, to get a good notion of what's going on inside a directory: `du -h --max-depth=1` – matanster Dec 08 '17 at 10:24
14

if you just want to see the aggregate size of the folder and probably in MB or GB format, please try the below script

$du -s --block-size=M /path/to/your/directory/
Sebastian
  • 16,813
  • 4
  • 49
  • 56
Shivraaz
  • 207
  • 2
  • 3
  • 2
    on os x, the flags are `-g` for 1-Gbyte and `-m` for 1-Mbyte counts. via `man du` – Sgnl Dec 30 '17 at 01:13
5
# 10GB
SIZE="10"


# check the current size
CHECK="`du -hs /media/662499e1-b699-19ad-57b3-acb127aa5a2b/Aufnahmen`"
CHECK=${CHECK%G*}
echo "Current Foldersize: $CHECK GB"

if (( $(echo "$CHECK > $SIZE" |bc -l) )); then
        echo "Folder is bigger than $SIZE GB"
else
        echo "Folder is smaller than $SIZE GB"
fi
Gutz-Pilz
  • 319
  • 6
  • 16
5

If it helps, You can also create an alias in your .bashrc or .bash_profile.

function dsize()
{
    dir=$(pwd)
    if [ -n "$1" ]; then
            dir=$1
    fi
    du -hs "$dir"
}

This prints the size of the current directory or the directory you have passed as an argument.

Vignesh Raja
  • 7,927
  • 1
  • 33
  • 42
  • This is a great answer – d8aninja Jul 18 '18 at 14:46
  • 1
    You should quote `$dir` when passing it to `du` to prevent word splitting for the value of `$dir`. Wrapping the call to `du` into `echo $(…)` seems redundant. Instead of calling `pwd` you can use the builtin Bash variable `${PWD}`. For checking if a variable is set, I suggest `[ -v varname ]`. – Toni Dietze Apr 10 '21 at 12:59