Script To Add A Swap File

A certain operation needed more as 20 GB of memory. Because my system only has 14 GB RAM and 9 GB swap that was a problem. I could have manually created a swapfile, but I thought maybe other people have sometimes the same problem. And I thought it a nice example of how to create a Bash script.


The main part is what you mostly would do yourself when creating and adding the swapfile manually:

   echo date "+%T: Creating ${_swapFile}"

   dd if=/dev/zero of=${_swapFile} bs=1024 count=$(($_gb * 1024 ** 2))

   echo

   chmod 600 ${_swapFile}

   mkswap   ${_swapFile}

   swapon   ${_swapFile}


I always prepend read only variables with a _. So variables that start with a _ are read only.

You could say it is a small script, so why bother, but I think it is 'always' a good idea to make variables that should not change read only.

When you need to calculate something in Bash you do this with $((expression)).

You use ** for exponential, so 1024 ** 2 gives a million.

Block count is a kilobyte, so I need a million blocks pro gigabyte.

That is why the calculation is done with $(($_gb * 1024 ** 2))



It would be nice to see the effect, so before this I have:

   echo Current Swap:

   swapon


and after I have:

   echo New Swap:

   swapon



We need to be sure the swapfile is not to big. I think that the swapfile should be less as a quarter of the free space on the partition it is created on:

   declare -ir _gbFree=$(getFreeGB ${_swapFile})

   # Make sure swapfile is less as a quarter of free space

   if [[ ${_gbFree} -le $(($_gb * 4)) ]] ; then

       giveError "Not enough space for swap file ($_gb, ${_gbFree})"

   fi


When you need the output of a command you use $(command).

I defined the function getFreeGB to get the free GB on a partition:

   function getFreeGB {

       df -BG $(dirname $1) | \

           tail -n 1       | \

           awk '{print substr($4, 1, length($4) - 1)}'

   }


With 'df -BG' the output is in gigabytes.

I am only interested in the last line, so I use tail -n 1.

The free space is the fourth field that is output and I need to remove the G. That is where the awk command is for.


I defined the function giveError for when something goes wrong:

   function giveError {

       echo $1

       exit 1

   }



Before that I do some more checks:

   if [[ $(id --user) -ne 0 ]] ; then

       giveError "${_scriptName} should be run as root"

   fi

   if [[ $# -ne 2 ]] ; then

       giveError "ERROR: ${_scriptName} SWAPFILE GB"

   fi

   declare -r _swapFile=$1

   declare -ir _gb=$2


   if [[ -e ${_swapFile} ]] ; then

       giveError "${_swapFile} already exists"

   fi



I also need the name of the script:

   declare -r _scriptName=$(basename ${0})



And I start my scripts with:

   #!/usr/bin/env bash


   set -o errexit

   set -o nounset


This makes sure that bash is found. The executable can be located in different places on different systems.

I also want the script to terminate on an error and an unset variable be an error.



I am curious what you think about this script and if you like me to share other scripts and what kind of scripts.

Is my explanation a bit sparse, or to broad?


You can get the script here: addSwapFile.sh.

There was a problem with the link to the script, but that is now solved.

Like
Reply

To view or add a comment, sign in

More articles by Cecil Westerhof

Others also viewed

Explore content categories