1

I'm doing some testing of a product on Apple and Android devices. I'd like a script that will fill up the devices hard drive until 100KB space is left on the drive it's runs against to. Also in linux systems I use dd if=/dev/zero of=zeros bs=1M to fill up the hdd entirely, but.. How do I make it fill up the hdd until certain amount of space is left? I'd like this both for linux command line or a bat script(windows) Example of a shell script and a windows batch script would be the best! Thanks!

2 Answers2

4

Do you need to write a real file, or are dummy files sufficient? The dd method you're using is going to be pretty slow for large drives . . .

In Windows, you can use fsutil file createnew <filename> <length_in_bytes> which will create a filler file. Here's a technet page with some more details.

In linux, fallocate works similarly, e.g. fallocate -l 10G 10gig_filler. Here's a previous SU question on creating filler files, as well as a slightly more technical version on Stack Overflow.

ernie
  • 6,323
  • 3
    fallocate actually creates a non-sparse file, but only if your filesystem supports that syscall (otherwise it just fails). ext4 and xfs are the only really common filesystems that support it. – jjlin Dec 11 '13 at 00:16
  • fsutil creates sparse file, not filling HDD with real zero bytes! – Maris B. Jul 30 '15 at 09:57
0

In Linux you could do something like this to leave only 1M*:

avail=$( df --output=source,avail -BM | grep sda6 | 
        awk '{print $NF}' | sed s/M//i); size=$((avail-left)  ); 
fallocate -l $sizeM filler_file;

The trick is parsing df to get the space available and then using fallocate to create a file of the necessary size. However, as @jjlin pointed out, the fallocate call will not work on all filesystems.

You can turn the little script above into a function to make it easier to use and also have it use an alternative method to create the file when on a filesystem that does not support fallocate (though fallocate is much faster and should be preferred where possible). Just add these lines to your ~/.bashrc (or equivalent for other shells):

fill_disk(){
    ## The space you want left
    left=$1 
    ## The unit you are using (Units are K, M, G,  T,  P, E, Z, Y (powers of 1024) or 
    ## KB, MB, ... (powers of 1000).
    unit=$2 
    ## The target drive
    disk=$3 
    ## The file name to create, make sure it is on the right drive.
    outfile=$4
    ## The space currently available on the target drive
    avail=$(df --output=source,avail -B$unit | grep $disk | awk '{print $NF}' | sed s/$unit//i); 
    ## The size of the file to be created
    size=$((avail-left))
    ## Skip if the available free space is already less than what requested
    if [ "$size" -gt 0 ]; then
    ## Use fallocate if possible, fall back to head otherwise
    fallocate -l $size$unit $outfile 2>/dev/null || head -c $size$unit /dev/zero > $outfile
    else 
    echo "There is already less then $left space available on $disk"
    fi
}

You can then launch it like this:

fill_disk desired_free_space unit target_disk out_file

For example, to create a file called /foo.txt that will leave only 100M free on / (sda1), run

fill_disk 100 M sda1 /foo.txt

Just make sure the target file is on the drive you want to fill, the function does not check for that.

* I couldn't get it to work reliably for small sizes, either it would run out of space or give me slightly different values from those I requested.


As requested, here's the same thing as a script:

#!/bin/env/bash
left=$1 
unit=$2 
disk=$3 
outfile=$4
avail=$(df --output=source,avail -B$unit | grep $disk | awk '{print $NF}' | sed s/$unit//i); 
size=$((avail-left))
if [ "$size" -gt 0 ]; then
  fallocate -l $size$unit $outfile 2>/dev/null || head -c $size$unit /dev/zero > $outfile
else 
  echo "There is already less then $left space available on $disk"
fi

Save it as fill_disk.sh and run like this:

bash fill_disk.sh 100 M sda1 /foo.txt
terdon
  • 53,403