Search code examples
memorylinux-disk-free

Pause a process before disk is full


Certain processes (like git gc --aggressive) take a long time to run, take up lots of disk space, and die if I run out of disk space. I'd like to pause them if the disk will run out of space soon, so I have time to free up some memory. How can I do this?


Solution

  • Here is an initial solution for Mac OS X. Suggestions welcome!

    #!/bin/bash
    
    # Change these variables as necessary.
    FILESYSTEM="/dev/disk1"
    DF=/usr/local/opt/coreutils/libexec/gnubin/df
    OSASCRIPT=/usr/bin/osascript
    
    if ! [[ -x $DF ]]; then echo "Error: $DF isn't executable."; exit 1; fi
    
    PID=$1
    STOPAT=$2
    
    # Verify input
    if [[ -n ${PID//[0-9]/} ]]; then echo "Error: The first parameter should be an integer"; exit 1; fi
    if [[ -n ${STOPAT//[0-9]/} ]]; then echo "Error: The second parameter should be an integer"; exit 1; fi
    
    RED='\033[0;31m'; PURPLE='\033[0;35m'; BLUE='\033[0;36m'
    NC='\033[0m' # No Color
    
    echo -e "Will pause the following process when there are ${PURPLE}$STOPAT${NC} bytes left on ${PURPLE}$FILESYSTEM${NC}"
    
    PROCESS=`ps -p $PID | grep $PID`
    echo -e "${BLUE}$PROCESS${NC}"
    
    # Check every second to see if FILESYSTEM has more than STOPAT bytes left.
    while true; do
        left=`$DF | grep -m 1 $FILESYSTEM | tr -s ' ' | cut -d" " -f4`
        echo -ne "$left bytes left\r";
        if [[ $left -lt $STOPAT ]]; then
            MSG="pausing process...$PID";
            echo $MSG;
            if [[ -x $OSASCRIPT ]]; then
                 $OSASCRIPT -e "display notification \"$MSG\""
            fi
            kill -TSTP $PID
            break
        fi
        sleep 1s
    done