#!/bin/bash # Warning : this script calls heavily on sudo for swapfile manipulation. # This is not clean. # But it is easier in my workflow. # Please consider removing all "sudo" from this file, # and calling it with administrative rights # if you want to use it in a proper way. usage="$0 -d DIR -n NAME -s SIZE -p PRIO add|remove Add or remove swapfiles to micro-manage disk usage. -i : Interactively prompt for parameters. (other options are NOT ignored, but set as preselection) -d DIR : Set DIRectory to place swapfile in. Default: /mnt -n NAME : Set filename for the swapfile. Default: swapfileN -s SIZE : SIZE in MB (only when creating a swapfile). Default: 1024 -p PRIO : Priority to use with swapon. Range from 0 to 1000. Default: 500 -f : Do not edit fstab with the changes. Default: edit fstab -h : Display this help and exit." if test $# -eq 0 ; then echo -e "$usage" echo "You must provide either 'add' or 'remove' !" exit 1 fi SWAP_FOLDER="/mnt" SWAP_FILENAME="swapfile" SWAP_SIZE="1024" #in MB SWAP_PRIO_MAX=750 #range 0..1000 SWAP_PRIO_INC=50 FSTAB=true sep="\n\t#############\n" while getopts ifhp:s:n:d: arg ; do case $arg in h) echo -e "$usage" ; exit 0 ;; i) INT=true ;; f) FSTAB=false ;; d) SWAP_FOLDER="$OPTARG" ;; n) SWAP_FILENAME="$OPTARG" ;; s) if test "$OPTARG" -gt 0 2> /dev/null ; then SWAP_SIZE="$OPTARG" else echo -e "invalid argument: -s $OPTARG\t (size expected in MB without suffix)" exit 1 fi ;; p) SWAP_PRIO_MAX="$OPTARG" ;; *) echo -e "$usage" ; echo "Invalid option: $arg"; exit 1 ;; esac done shift $((( $OPTIND - 1 ))) if test "$1" = "add" ; then MODE="add" elif test "$1" = "remove" ; then MODE="remove" elif test "$INT" != true ; then echo -e "$usage" echo "You must provide either add or remove !" exit 1 fi if test "$INT" = true ; then if test "$MODE" != "add" -a "$MODE" != "remove" ; then until test "$REPLY" = "add" -o "$REPLY" = "remove" -o "$REPLY" = "quit" do read -p "Mode [add|remove|quit]: " done test "$REPLY" = "quit" && exit 0 MODE=$REPLY unset REPLY fi until test -d "$REPLY" do read -e -i "$SWAP_FOLDER" -p "Directory : " done SWAP_FOLDER=$REPLY unset REPLY if test "$MODE" = "add" ; then read -e -i "$SWAP_FILENAME" -p "Filename : " SWAP_FILENAME=$REPLY unset REPLY until test "$REPLY" -gt 0 2> /dev/null ; do read -e -i "$SWAP_SIZE" -p "Swapfile size (MiB) : " done SWAP_SIZE="$REPLY" unset REPLY until test "$REPLY" -gt 0 2> /dev/null ; do read -e -i "$SWAP_PRIO_MAX" -p "Swap priority {0-1000} : " done SWAP_PRIO_MAX="$REPLY" unset REPLY fi until test "$REPLY" = "y" -o "$REPLY" = "n" do read -e -i "$(test "$FSTAB" = true && echo y || echo n)" -p "Update fstab ? [y|n]: " done test "$REPLY" = "n" && FSTAB=false unset REPLY echo ; echo " About to run the following command:" echo $0 -d "$SWAP_FOLDER" -n "$SWAP_FILENAME" -s "$SWAP_SIZE" -p "$SWAP_PRIO_MAX" -f "$MODE" until test "$REPLY" = "y" -o "$REPLY" = "n" do read -p "Proceed ? [y|n]: " done test "$REPLY" != "y" && exit 1 fi if test "$MODE" = "add" ; then N=$(ls $SWAP_FOLDER/$SWAP_FILENAME* | wc -l) swapfile=$SWAP_FOLDER/$SWAP_FILENAME$N prio=$((($SWAP_PRIO_MAX - $N * $SWAP_PRIO_INC))) echo -e "$sep Creating swapfile: $swapfile$sep" dd if=/dev/urandom of=$swapfile bs=1M count=$SWAP_SIZE status=progress chmod 0600 $swapfile mkswap -c -L $SWAP_FILENAME$N $swapfile swapon -p $prio $swapfile echo -e "\n\n" swapon elif test "$MODE" = "remove" ; then N=$(ls $SWAP_FOLDER/$SWAP_FILENAME* | wc -l) swapfile=$SWAP_FOLDER/$SWAP_FILENAME$((($N - 1))) echo -e "$sep Removing swapfile: $swapfile$sep" swapoff $swapfile && sudo rm $swapfile echo -e "\n\n" swapon fi if test "$FSTAB" = true ; then echo -e "$sep Editing /etc/fstab accordingly$sep" tmpfile=/tmp/swapctl.fstab if test "$MODE" = "add" ; then cat /etc/fstab > $tmpfile echo -e "$swapfile\t\t\t\t\t\t\t\tnone\t\t\tswap\tsw,pri=$prio\t\t\t0\t\t0" >> $tmpfile else cat /etc/fstab | grep -v $swapfile > $tmpfile fi echo -e "# The lines below this one will be the new fstab file : \n\n$(cat $tmpfile)" | more while true ; do echo -e "$sep What to do with this fstab ?" echo -e "[ \e[4ma\\e[0mccept changes | \e[4me\e[0mdit file | dis\e[4mc\e[0mard changes | show \e[4md\e[0miff ]" read -p "[ a | e | c | d ]: " prompt case $prompt in a|accept) mv /etc/fstab.2 /etc/fstab.3 mv /etc/fstab.1 /etc/fstab.2 mv /etc/fstab /etc/fstab.1 mv $tmpfile /etc/fstab echo -e "$sep Changes accepted. New contents of /etc/fstab :$sep" cat /etc/fstab | more break ;; e|edit) ${EDITOR:-nano} $tmpfile ;; c|discard) echo -e "$sep Changes discarded. /etc/fstab remains unchanged.$sep" break ;; d|diff) echo -e "\n\n\tdiff\t\t/etc/fstab\t\t\t\t\t\t/tmp/swapctl.fstab\n" diff --tabsize=4 -E -Z -b -t -y /etc/fstab /tmp/swapctl.fstab | more ;; esac done fi