amuck-landowner

The Helpful Server Admin Script Thread

TruvisT

Server Management Specialist
Verified Provider
Figure it would be cool if we had a thread just for sharing scripts that help make jobs easier. They can be well known, custom, or even simple one liners to help make your life easier.
 
When posting please place your script(s) in CODE tags and be sure to explain what the script does and how/when to use it.
 

I will continue to add more scripts as I find them on our servers and script dumps stored locally.
 
 
Firewalling IP's flooding access logs based on a STRING:


grep "BIG STRING" /file/name | grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" | sort -u | /usr/bin/xargs --max-args=1 /usr/sbin/csf -d
Count # of IPs in an Access Log:


#!/bin/bash

FILE=/usr/local/apache/logs/access_log;
 for ip in `cat $FILE |cut -d ' ' -f 1 |sort |uniq`;
 do { COUNT=`grep ^$ip $FILE |wc -l`;
 if [[ "$COUNT" -gt "10" ]]; then echo "$COUNT:   $ip";
 fi }; done 
CRONTAB Lister. This script helps by listing ALL cron jobs on the linux server:


#!/bin/bash

# System-wide crontab file and cron job directory. Change these for your system.
CRONTAB='/etc/crontab'
CRONDIR='/etc/cron.d'

# Single tab character. Annoyingly necessary.
tab=$(echo -en "\t")

# Given a stream of crontab lines, exclude non-cron job lines, replace
# whitespace characters with a single space, and remove any spaces from the
# beginning of each line.
function clean_cron_lines() {
    while read line ; do
        echo "${line}" |
            egrep --invert-match '^($|\s*#|\s*[[:alnum:]_]+=)' |
            sed --regexp-extended "s/\s+/ /g" |
            sed --regexp-extended "s/^ //"
    done;
}

# Given a stream of cleaned crontab lines, echo any that don't include the
# run-parts command, and for those that do, show each job file in the run-parts
# directory as if it were scheduled explicitly.
function lookup_run_parts() {
    while read line ; do
        match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+')

        if [[ -z "${match}" ]] ; then
            echo "${line}"
        else
            cron_fields=$(echo "${line}" | cut -f1-6 -d' ')
            cron_job_dir=$(echo  "${match}" | awk '{print $NF}')

            if [[ -d "${cron_job_dir}" ]] ; then
                for cron_job_file in "${cron_job_dir}"/* ; do  # */ <not a comment>
                    [[ -f "${cron_job_file}" ]] && echo "${cron_fields} ${cron_job_file}"
                done
            fi
        fi
    done;
}

# Temporary file for crontab lines.
temp=$(mktemp) || exit 1

# Add all of the jobs from the system-wide crontab file.
cat "${CRONTAB}" | clean_cron_lines | lookup_run_parts >"${temp}"

# Add all of the jobs from the system-wide cron directory.
cat "${CRONDIR}"/* | clean_cron_lines >>"${temp}"  # */ <not a comment>

# Add each user's crontab (if it exists). Insert the user's name between the
# five time fields and the command.
while read user ; do
    crontab -l -u "${user}" 2>/dev/null |
        clean_cron_lines |
        sed --regexp-extended "s/^((\S+ +){5})(.+)$/\1${user} \3/" >>"${temp}"
done < <(cut --fields=1 --delimiter=: /etc/passwd)

# Output the collected crontab lines. Replace the single spaces between the
# fields with tab characters, sort the lines by hour and minute, insert the
# header line, and format the results as a table.
cat "${temp}" |
    sed --regexp-extended "s/^(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(.*)$/\1\t\2\t\3\t\4\t\5\t\6\t\7/" |
    sort --numeric-sort --field-separator="${tab}" --key=2,1 |
    sed "1i\mi\th\td\tm\tw\tuser\tcommand" |
    column -s"${tab}" -t

rm --force "${temp}"
Basic Security Checking Script:


#!/bin/bash
#
# Copyright (C) 2009 Tobias Klein.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Tobias Klein.
# 4. The name Tobias Klein may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Name : checksec.sh
# Version : 1.1
# Author : Tobias Klein
# Date : December 2009
# Download: http://www.trapkit.de/tools/checksec.html
#
# Description:
#
# Modern Linux distributions offer some mitigation techniques to make it
# harder to exploit software vulnerabilities reliably. Mitigations such
# as RELRO, NoExecute (NX), Stack Canaries, Address Space Layout
# Randomization (ASLR) and Position Independent Executables (PIE) have
# made reliably exploiting any vulnerabilities that do exist far more
# challenging. The checksec.sh script is designed to test what *standard*
# Linux OS security features are being used. While other mitigations do
# exist (e.g. grsecurity.net) these are not tested.
#

# help
if [ "$#" = "0" ]; then
echo "usage: checksec OPTIONS"
echo -e "\t--file <binary name>"
echo -e "\t--dir <directory name>"
echo -e "\t--proc <process name>"
echo -e "\t--proc-all"
echo -e "\t--proc-libs <process ID>"
echo -e "\t--version"
echo
exit 1
fi

# version information
version() {
echo "checksec v1.1, Tobias Klein, www.trapkit.de, December 2009"
echo
}

# check file(s)
filecheck() {
# check for RELRO support
if readelf -l $1 2>/dev/null | grep -q 'GNU_RELRO'; then
if readelf -d $1 2>/dev/null | grep -q 'BIND_NOW'; then
echo -n -e '\033[32mFull RELRO \033[m '
else
echo -n -e '\033[33mPartial RELRO\033[m '
fi
else
echo -n -e '\033[31mNo RELRO \033[m '
fi

# check for stack canary support
if readelf -s $1 2>/dev/null | grep -q '__stack_chk_fail'; then
echo -n -e '\033[32mCanary found \033[m '
else
echo -n -e '\033[31mNo canary found\033[m '
fi

# check for NX support
if readelf -l $1 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then
echo -n -e '\033[31mNX disabled\033[m '
else
echo -n -e '\033[32mNX enabled \033[m '
fi

# check for PIE support
if readelf -h $1 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then
echo -n -e '\033[31mNo PIE \033[m '
elif readelf -h $1 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then
if readelf -d $1 2>/dev/null | grep -q '(DEBUG)'; then
echo -n -e '\033[32mPIE enabled \033[m '
else
echo -n -e '\033[33mDynamic Shared Object\033[m '
fi
else
echo -n -e '\033[33mNot an ELF file \033[m '
fi
}

# check process(es)
proccheck() {
# check for RELRO support
if readelf -l $1/exe 2>/dev/null | grep -q 'Program Headers'; then
if readelf -l $1/exe 2>/dev/null | grep -q 'GNU_RELRO'; then
if readelf -d $1/exe 2>/dev/null | grep -q 'BIND_NOW'; then
echo -n -e '\033[32mFull RELRO \033[m '
else
echo -n -e '\033[33mPartial RELRO \033[m '
fi
else
echo -n -e '\033[31mNo RELRO \033[m '
fi
else
echo -n -e '\033[33mPermission denied\033[m\n'
exit 1
fi

# check for stack canary support
if readelf -s $1/exe 2>/dev/null | grep -q 'Symbol table'; then
if readelf -s $1/exe 2>/dev/null | grep -q '__stack_chk_fail'; then
echo -n -e '\033[32mCanary found \033[m '
else
echo -n -e '\033[31mNo canary found \033[m '
fi
else
if [ "$1" != "1" ]; then
echo -n -e '\033[33mPermission denied \033[m '
else
echo -n -e '\033[33mNo symbol table found\033[m '
fi
fi

# first check for PaX support
if cat $1/status 2> /dev/null | grep -q 'PaX:'; then
pageexec=( $(cat $1/status 2> /dev/null | grep 'PaX:' | cut -b6) )
segmexec=( $(cat $1/status 2> /dev/null | grep 'PaX:' | cut -b10) )
mprotect=( $(cat $1/status 2> /dev/null | grep 'PaX:' | cut -b8) )
randmmap=( $(cat $1/status 2> /dev/null | grep 'PaX:' | cut -b9) )
if [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "M" && "$randmmap" = "R" ]]; then
echo -n -e '\033[32mPaX enabled\033[m '
elif [[ "$pageexec" = "p" && "$segmexec" = "s" && "$randmmap" = "R" ]]; then
echo -n -e '\033[33mPaX ASLR only\033[m '
elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "m" && "$randmmap" = "R" ]]; then
echo -n -e '\033[33mPaX mprot off \033[m'
elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "M" && "$randmmap" = "r" ]]; then
echo -n -e '\033[33mPaX ASLR off\033[m '
elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "m" && "$randmmap" = "r" ]]; then
echo -n -e '\033[33mPaX NX only\033[m '
else
echo -n -e '\033[31mPaX disabled\033[m '
fi
# fallback check for NX support
elif readelf -l $1/exe 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then
echo -n -e '\033[31mNX disabled\033[m '
else
echo -n -e '\033[32mNX enabled \033[m '
fi

# check for PIE support
if readelf -h $1/exe 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then
echo -n -e '\033[31mNo PIE \033[m '
elif readelf -h $1/exe 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then
if readelf -d $1/exe 2>/dev/null | grep -q '(DEBUG)'; then
echo -n -e '\033[32mPIE enabled \033[m '
else
echo -n -e '\033[33mDynamic Shared Object\033[m '
fi
else
echo -n -e '\033[33mNot an ELF file \033[m '
fi
}

# check mapped libraries
libcheck() {
libs=( $(awk '{ print $6 }' /proc/$1/maps | grep '/' | sort -u | xargs file | grep ELF | awk '{ print $1 }' | sed 's/:/ /') )

printf "\n* Loaded libraries (file information, # of mapped files: ${#libs[@]}):\n\n"

for element in $(seq 0 $((${#libs[@]} - 1)))
do
echo " ${libs[$element]}:"
echo -n " "
filecheck ${libs[$element]}
printf "\n\n"
done
}

# check for system-wide ASLR support (kernel.randomize_va_space)
# (see the kernel file 'Documentation/sysctl/kernel.txt' for a detailed description)
aslrcheck() {
if cat /proc/1/status 2> /dev/null | grep -q 'PaX:'; then
printf ": "
if cat /proc/1/status 2> /dev/null | grep 'PaX:' | grep -q 'R'; then
echo -n -e '\033[32mPaX ASLR Enabled\033[m\n\n'
else
echo -n -e '\033[31mPaX ASLR Disabled\033[m\n\n'
fi
else
printf " (kernel.randomize_va_space): "
if /sbin/sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 1'; then
echo -n -e '\033[33mOn (Setting: 1)\033[m\n\n'
printf " Description - Make the addresses of mmap base, stack and VDSO page randomized.\n"
printf " This, among other things, implies that shared libraries will be loaded to \n"
printf " random addresses. Also for PIE-linked binaries, the location of code start\n"
printf " is randomized. Heap addresses are *not* randomized.\n\n"
elif /sbin/sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 2'; then
echo -n -e '\033[32mOn (Setting: 2)\033[m\n\n'
printf " Description - Make the addresses of mmap base, heap, stack and VDSO page randomized.\n"
printf " This, among other things, implies that shared libraries will be loaded to random \n"
printf " addresses. Also for PIE-linked binaries, the location of code start is randomized.\n\n"
elif /sbin/sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 0'; then
echo -n -e '\033[31mOff (Setting: 0)\033[m\n'
else
echo -n -e '\033[32mNot supported\033[m\n'
fi
printf " See the kernel file 'Documentation/sysctl/kernel.txt' for more details.\n\n"
fi
}

# check cpu nx flag
nxcheck() {
if grep -q nx /proc/cpuinfo; then
echo -n -e '\033[32mYes\033[m\n\n'
else
echo -n -e '\033[31mNo\033[m\n\n'
fi
}

if [ "$1" = "--dir" ]; then
cd $2
printf "RELRO STACK CANARY NX/PaX PIE FILE\n"
for N in [a-z]*; do
if [ "$N" != "[a-z]*" ]; then
filecheck $N
if [ `find $2$N \( -perm -004000 -o -perm -002000 \) -type f -print` ]; then
printf "\033[37;41m%s%s\033[m" $2 $N
else
printf "%s%s" $2 $N
fi
echo
fi
done
exit 0
fi

if [ "$1" = "--file" ]; then
printf "RELRO STACK CANARY NX/PaX PIE FILE\n"
filecheck $2
if [ `find $2 \( -perm -004000 -o -perm -002000 \) -type f -print` ]; then
printf "\033[37;41m%s%s\033[m" $2 $N
else
printf "%s" $2
fi
echo
exit 0
fi

if [ "$1" = "--proc-all" ]; then
cd /proc
printf "* System-wide ASLR"
aslrcheck
printf "* Does the CPU support NX: "
nxcheck
printf " COMMAND PID RELRO STACK CANARY NX/PaX PIE\n"
for N in [1-9]*; do
if [ $N != $$ ] && readlink -q $N/exe > /dev/null; then
printf "%16s" `head -1 $N/status | cut -b 7-`
printf "%7d " $N
proccheck $N
echo
fi
done
exit 0
fi

if [ "$1" = "--proc" ]; then
cd /proc
printf "* System-wide ASLR"
aslrcheck
printf "* Does the CPU support NX: "
nxcheck
printf " COMMAND PID RELRO STACK CANARY NX/PaX PIE\n"
for N in `pidof $2`; do
if [ -d $N ]; then
printf "%16s" `head -1 $N/status | cut -b 7-`
printf "%7d " $N
proccheck $N
echo
fi
done
fi

if [ "$1" = "--proc-libs" ]; then
cd /proc
printf "* System-wide ASLR"
aslrcheck
printf "* Does the CPU support NX: "
nxcheck
printf "* Process information:\n\n"
printf " COMMAND PID RELRO STACK CANARY NX/PaX PIE\n"
N=$2
if [ -d $N ]; then
printf "%16s" `head -1 $N/status | cut -b 7-`
printf "%7d " $N
proccheck $N
echo
libcheck $N
fi
fi

if [ "$1" = "--version" ]; then
version
fi
Create BIND/DNS Records Template Script:

Code:
#!/bin/bash
# A Bash shell script to create BIND ZONE FILE.
# Tested under BIND 8.x / 9.x, RHEL, DEBIAN, Fedora Linux.
# -------------------------------------------------------------------------
# Copyright (c) 2002,2009 Vivek Gite <[email protected]>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
# Examples:
# ./mkzone.sh example.com default-www-IP-address
# ./mkzone.sh cyberciti.biz 74.12.5.1
# ./mkzone.sh cyberciti.com 202.54.1.2 ns.profile.nixcraft.net > /var/named/chroot/etc/bind/master/c/cyberciti.com
# -------------------------------------------------------------------------
# Last updated on: Mar/24/2007 - Fixed a few bugs.
# -------------------------------------------------------------------------
DOMAIN="$1"
WWWIP="$2"
 
if [ $# -le 1 ]
then
    echo "Syntax: $(basename $0) domainname www.domain.ip.address [profile]"
    echo "$(basename $0) example.com 1.2.3.4"
    exit 1
fi
 
# get profile
PROFILE="ns.profile.nixcraft.net"
[ "$3" != "" ] && PROFILE="$3"
 
SERIAL=$(date +"%Y%m%d")01                     # Serial yyyymmddnn
 
# load profile
source "$PROFILE"
 
# set default ns1
NS1=${NAMESERVERS[0]}
 
###### start SOA ######
echo "\$ORIGIN ${DOMAIN}."
echo "\$TTL ${TTL}"
echo "@    IN    SOA    ${NS1}    ${EMAILID}("
echo "            ${SERIAL}    ; Serial yyyymmddnn"
echo "            ${REFRESH}        ; Refresh After 3 hours"
echo "            ${RETRY}        ; Retry Retry after 1 hour"
echo "            ${EXPIER}        ; Expire after 1 week"
echo "            ${MAXNEGTIVE})        ; Minimum negative caching of 1 hour"
echo ""
 
###### start Name servers #######
# Get length of an array
tLen=${#NAMESERVERS[@]}
 
# use for loop read all nameservers
echo "; Name servers for $DOMAIN"
for (( i=0; i<${tLen}; i++ ));
do
    echo "@            ${ATTL}    IN    NS    ${NAMESERVERS[$i]}"
done
 
###### start MX section #######
# get length of an array
tmLen=${#MAILSERVERS[@]}
 
# use for loop read all mailservers
echo "; MX Records"
for (( i=0; i<${tmLen}; i++ ));
do
    echo "@            ${ATTL}    IN     MX    $(( 10*${i} + 10 ))    ${MAILSERVERS[$i]}"
done
 
###### start A pointers #######
# A Records - Default IP for domain
echo '; A Records'
echo "@             ${ATTL}    IN     A    ${WWWIP}"
 
# Default Nameserver IPs
# get length of an array
ttLen=${#NAMESERVERSIP[@]}
 
# make sure both nameserver and their IP match
if [ $tLen -eq $ttLen ]
then
# use for loop read all nameservers IPs
for (( i=0; i<${ttLen}; i++ ));
do
      thisNs="$(echo ${NAMESERVERS[$i]} | cut -d'.' -f1)"
 
    echo "${thisNs}             ${ATTL}    IN    A    ${NAMESERVERSIP[$i]}"
done
else
    # if we are here means, our nameserver IPs are defined else where else...  do nothing
    :
fi
 
echo "; CNAME Records"
echo "www            ${ATTL}    IN    CNAME    @"
 
LoadCutomeARecords
 
Last edited by a moderator:

drmike

100% Tier-1 Gogent
Wow!  Interesting collection of stuff.

I like these and similar.   Amazing what can be done / is out there... Now just to find it :)
 

marlencrabapple

New Member
It would be amazing if there were scripts like this for email related stuff. I don't think I've ever dealt with anything more confusing than exim.
 

KuJoe

Well-Known Member
Verified Provider
Here are some of my favorites I've had for years:

Count the number of connections per IP:


netstat -plan | awk '{print $5}' | awk -F : '{print $(NF-1)}' | egrep -v "Address|and|servers|State|DGRAM|]|STREAM" | sort | uniq -c | sort -n

Count number of SMTP connection per IP:


netstat -antp --inet | awk '$4 ~ /:25$/' | awk '{print $4}' | awk -F : '{print $(NF-1)}' | egrep -v "127.0.0.1|127.0.0.2|Address|and|servers|State|DGRAM|]|STREAM" | sort | uniq -c | sort -n
The rest of the scripts are OpenVZ or hardware specific. :(
 

MartinD

Retired Staff
Verified Provider
Retired Staff
I've tided things up a little. Please stick to the topic at hand i.e. posting helpful code snippets. mikho, I'd suggest sending him a PM with your request though I do feel it would be detracting from the spirit in which the thread was meant.

Liking the idea of this - I have a stack of stuff *somewhere* that I'll add (quite a few are exim related, too!) if I can find them. Used them so often that they're implanted in my brain so don't need to c&p these days.

One word of caution though - as with all scripts, people should ensure they know what the script does before blindly running them - it doesn't take much to cripple a box running a dodgy script!
 

marlencrabapple

New Member
I'll pull some good exim scrips and post for you. What would you specifically like?
I just really want to figure out how to get dkim working properly. I don't know how many times I can follow a guide to the letter and screw it up before I give up and rm -rf everything.
 

GoodHosting

New Member
My homebrew "check_memory" script for use with NRPE active reporting (nagio-nrped):


#!/bin/sh

################################################################################
# Nagios plugin to monitor free memory on the local machine #
# Author: Damon Blais [Albino Geek Services Ltd.] ([email protected]) #
################################################################################

VERSION="Version 1.1"
AUTHOR="(c) 2013-2014 Albino Geek Services Ltd. ([email protected])"

PROGNAME=`/bin/basename $0`

# Constants
BYTES_IN_MB=$(( 1024 * 1024 ))
KB_IN_MB=1024

# Exit codes
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

# Helper functions #############################################################

function print_revision {
# Print the revision number
echo "$PROGNAME - $VERSION"
}

function print_usage {
# Print a short usage statement
echo "Usage: $PROGNAME [-v] -w <limit> -c <limit>"
}

function print_help {
# Print detailed help information
print_revision
echo "$AUTHOR\n\nCheck free memory on local machine\n"
print_usage

/bin/cat <<__EOT

Options:
-h
Print detailed help screen
-V
Print version information

-w INTEGER
Exit with WARNING status if less than INTEGER MB of memory are free
-w PERCENT%
Exit with WARNING status if less than PERCENT of memory is free
-c INTEGER
Exit with CRITICAL status if less than INTEGER MB of memory are free
-c PERCENT%
Exit with CRITICAL status if less than PERCENT of memory is free
-v
Verbose output
__EOT
}

# Main #########################################################################

# Total memory size (in MB)
tot_mem=$(( `/usr/bin/free | /usr/bin/head -2 | /usr/bin/tail -1 | /bin/awk '{print $2}'` / KB_IN_MB))
# Free memory size (in MB)
free_mem=$(( `/usr/bin/free | /usr/bin/tail -2 | /usr/bin/head -1 | /bin/awk '{print $4}'` / KB_IN_MB ))
# Free memory size (in percentage)
free_mem_perc=$(( free_mem * 100 / tot_mem ))

# Verbosity level
verbosity=0
# Warning threshold
thresh_warn=
# Critical threshold
thresh_crit=

# Parse command line options
while [ "$1" ]; do
case "$1" in
-h | --help)
print_help
exit $STATE_OK
;;
-V | --version)
print_revision
exit $STATE_OK
;;
-v | --verbose)
: $(( verbosity++ ))
shift
;;
-w | --warning | -c | --critical)
if [[ -z "$2" || "$2" = -* ]]; then
# Threshold not provided
echo "$PROGNAME: Option '$1' requires an argument"
print_usage
exit $STATE_UNKNOWN
elif [[ "$2" = +([0-9]) ]]; then
# Threshold is a number (MB)
thresh=$2
elif [[ "$2" = +([0-9])% ]]; then
# Threshold is a percentage
thresh=$(( tot_mem * ${2%\%} / 100 ))
else
# Threshold is neither a number nor a percentage
echo "$PROGNAME: Threshold must be integer or percentage"
print_usage
exit $STATE_UNKNOWN
fi
[[ "$1" = *-w* ]] && thresh_warn=$thresh || thresh_crit=$thresh
shift 2
;;
-?)
print_usage
exit $STATE_OK
;;
*)
echo "$PROGNAME: Invalid option '$1'"
print_usage
exit $STATE_UNKNOWN
;;
esac
done

if [[ -z "$thresh_warn" || -z "$thresh_crit" ]]; then
# One or both thresholds were not specified
echo "$PROGNAME: Threshold not set"
print_usage
exit $STATE_UNKNOWN
elif [[ "$thresh_crit" -gt "$thresh_warn" ]]; then
# The warning threshold must be greater than the critical threshold
echo "$PROGNAME: Warning free space should be more than critical free space"
print_usage
exit $STATE_UNKNOWN
fi

if [[ "$verbosity" -ge 2 ]]; then
# Print debugging information
/bin/cat <<__EOT
Debugging information:
Warning threshold: $thresh_warn MB
Critical threshold: $thresh_crit MB
Verbosity level: $verbosity
Total memory: $tot_mem MB
Free memory: $free_mem MB ($free_mem_perc%)
__EOT
fi

if [[ "$free_mem" -lt "$thresh_crit" ]]; then
# Free memory is less than the critical threshold
echo "MEMORY CRITICAL - $free_mem_perc% free ($free_mem MB out of $tot_mem MB)"
exit $STATE_CRITICAL
elif [[ "$free_mem" -lt "$thresh_warn" ]]; then
# Free memory is less than the warning threshold
echo "MEMORY WARNING - $free_mem_perc% free ($free_mem MB out of $tot_mem MB)"
exit $STATE_WARNING
else
# There's enough free memory!
echo "MEMORY OK - $free_mem_perc% free ($free_mem MB out of $tot_mem MB)"
exit $STATE_OK
fi


Based on the "check_hdd" script, and a few snippets online, compiled together into this.
 
Top
amuck-landowner