Outils pour utilisateurs

Outils du site


blog

Script HA supersivion Nagios routeur actif par SNMP

check_snmp_active_router.sh

#! /bin/bash
 
# Creative Commons CC0 Public Domain Licence
 
set -euo pipefail
IFS=$' \t\n'
export LC_ALL=C
 
OID_HOSTNAME=.1.3.6.1.2.1.1.5.0
LABEL="ACTIVE_ROUTER"
 
ALL_ARGS=("$@")
 
exec 6>&1 # Link file descriptor #6 with stdout. Saves stdout.
 
# FIX IGNORED ~/.snmp/snmp.conf WHEN 'sudo -u nagios check_snmp_host.sh'
HOME=$(getent passwd "$(whoami)" | cut -d: -f6)
 
PATH="/sbin:/usr/sbin:$PATH"
 
exit_malfunction() {
	exec 1>&6 6>&- # Restore stdout and close file descriptor #6
	echo "${LABEL} ${STATUS_MSG} - ERROR $*"
	exit 3
}
 
# NAGIOS EXIT STATUS
# STATE_OK=0 ; STATE_WARNING=1 ; STATE_CRITICAL=2 ; STATE_UNKNOWN=3; STATE_DEPENDENT=4
STATUS_MSG=UNKNOWN
typeset -i STATUS_CODE=3
trap 'if [ $STATUS_CODE -eq 3 ] && [ $? -ne 0 ] ; then
  exit_malfunction "Unexpected error"
fi' EXIT ERR
 
command_exists() {
	command -v "$1" >/dev/null 2>&1 || (
		exit_malfunction "I require $1 but it's not installed. Aborting."
	)
}
 
command_exists snmpget
 
get_defaultgw() {
	ip -4 route show default | awk '/^default/ { print $3 }' || exit_malfunction "Can't get default gateway"
}
 
get_hostname() {
	local REMOTE_HOST=$1
	ROUTER_NAME=$(snmpget -r 2 "${ALL_ARGS[@]}" "$REMOTE_HOST" "${OID_HOSTNAME}" | cut -d= -f2 | cut -d: -f2 | xargs) || exit_malfunction "SNMP failed"
}
 
main() {
	local DEFAULTGW
	local -i ROUTER_NB
	DEFAULTGW=$(get_defaultgw)
	get_hostname "$DEFAULTGW"
	ROUTER_NB=$(echo "$ROUTER_NAME" | grep -o -e '[0-9]\+$') || exit_malfunction "Hostname error in '$ROUTER_NAME' for $DEFAULTGW"
	if [ "$ROUTER_NB" -eq 1 ]; then
		STATUS_CODE=0
		STATUS_MSG=OK
	elif [ "$ROUTER_NB" -eq 2 ]; then
		STATUS_CODE=1
		STATUS_MSG=WARNING
	else
		STATUS_CODE=2
		STATUS_MSG=CRITICAL
	fi
	echo "${LABEL} ${STATUS_MSG} - $ROUTER_NAME is active router"
 
}
 
main
exit $STATUS_CODE

FIXME

2025/03/24 15:06

Script en C

Tester un bout de code c sans le compiler grâce à TCC

sudo  apt-get install tcc

hello.c

#! /usr/bin/tcc -run
#include<stdio.h>
 
int main(void)
{
        puts("Hello world !");
        return 0;
}
chmod +x hello.c
./hello.c
2025/03/24 15:06

Script bash tab array list dict - Utilisation de listes et de tableaux en bash

Voir aussi :

  • readarray -t ronly

Listes

$ set |grep lplop
lplop=([0]="a" [1]="b" [2]="c" [3]="d")
declare -a liste
 
liste_append() {
         # SC2206 (warning): Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a
        liste=(${liste[@]} $1)
}
 
liste_count() {
        echo ${#liste[*]}
}
 
liste=(un deux)
 
 
echo ${liste[@]}
liste_count
 
liste_append trois
 
liste_count
echo ${liste[@]}
Boucles (loops)

SC2128 (warning): Expanding an array without an index only gives the first element.

Problematic code:

myarray=(foo bar)
for f in $myarray
do
  cat "$f"
done

Correct code:

myarray=(foo bar)
for f in "${myarray[@]}"
do
  cat "$f"
done

Dictionnaires

declare -A dict
$ declare -A D=( [UN]=1 [DEUX]=2 )
$ echo ${D[UN]}
1

Exemple

tab_fruits=("pomme" "poire" "tomate" "mandarine")
 
printf '%s\0' "${tab_fruits[@]}" | grep -F -x -z -- 'poire'
2025/03/24 15:06

Script bash RedHat CentOS comparaison des paquets installés entre deux machines

Exemple

Exemple 1
Entrées

rpms-ref.list

rpm-build-libs-4.11.1-16.el7.x86_64
rpm-4.11.1-16.el7.x86_64
rpm-python-4.11.1-16.el7.x86_64
rpm-libs-4.11.1-16.el7.x86_64
vim-common-7.4.160-1.el7.x86_64
vim-enhanced-7.4.160-1.el7.x86_64

rpms-local.list

rpm-python-4.11.3-21.el7.x86_64
rpm-libs-4.11.3-21.el7.x86_64
rpm-build-libs-4.11.3-21.el7.x86_64
rpm-4.11.3-21.el7.x86_64
atop-2.1-1.el7.x86_64
Exécution et sortie

Lister les paquets en trop / à effacer

$ ./comp-rpms.sh list-remove rpms-ref.list rpms-local.list
atop-2.1-1.el7.x86_64

Lister les paquets manquants / à installer

$ ./comp-rpms.sh list-install rpms-ref.list rpms-local.list
vim-common-7.4.160-1.el7.x86_64
vim-enhanced-7.4.160-1.el7.x86_64
Exemple 2

Rendre la Machine cible similaire à Machine référence

La machine cible doit avoir tous les dépôts de la machine de référence

Machine de référence

rpm -qa > rpms-ref.list

On dépose le fichier rpms-ref.list sur la Machine cible.

Machine cible

rpm -qa > rpms-local.list
 
yum remove $(./comp-rpms.sh list-remove rpms-ref.list rpms-local.list)
#for paq in $(./comp-rpms.sh list-remove rpms-ref.list rpms-local.list); do yum remove $paq ; done
 
LANG=C yum install --assumeno $(./comp-rpms.sh list-install-v rpms-ref.list rpms-local.list) | grep '^No package'
#yum install -y $(./comp-rpms.sh list-install-v rpms-ref.list rpms-local.list)
yum install -y $(./comp-rpms.sh list-install rpms-ref.list rpms-local.list)
 
yum downgrade $(./comp-rpms.sh list-same rpms-ref.list rpms-local.list)

Script

comp-rpms.sh

# !/bin/bash
 
FUNC=$1
REFERENCE=$2
CIBLE=$3
set -o nounset
 
 
regex-strip-version()
{
        local var=$1
        sed -e 's/-[0-9][0-9]*.*//g' $var
}
 
list-install()
{
        regex-strip-version $CIBLE > /tmp/rpm.list
 
        for PAQ in $(cat $REFERENCE)
        do
                grep "^$(regex-strip-version <(echo $PAQ))$" /tmp/rpm.list >/dev/null
                if [ $? -eq 1 ]
                then
                        echo "$PAQ"
                fi
        done
        rm -f /tmp/rpm.list
}
 
list-install-v()
{
        regex-strip-version <(list-install)
}
 
list-remove()
{
        regex-strip-version $REFERENCE > /tmp/rpm.list
 
        for PAQ in $(cat $CIBLE)
        do
                grep "^$(regex-strip-version <(echo $PAQ))$" /tmp/rpm.list >/dev/null
                if [ $? -eq 1 ]
                then
                        echo "$PAQ"
                fi
        done
}
 
list-remove-v()
{
        regex-strip-version <(list-remove)
}
 
list-same()
{
        regex-strip-version $CIBLE > /tmp/rpm.list
 
        for PAQ in $(cat $REFERENCE)
        do
                grep "^$(regex-strip-version <(echo $PAQ))$" /tmp/rpm.list >/dev/null
                if [ $? -eq 0 ]
                then
                        echo "$PAQ"
                fi
        done
        rm -f /tmp/rpm.list
}
 
list-same-v()
{
        regex-strip-version <(list-same)
}
 
usage()
{
        cat <<EOF
        $0 FONCTION <FICHIER REFERENCE> <FICHIER CIBLE>
        Exemple 1 :
           rpm -qa > rpms-local.list
           $0 list-remove rpms-ref.list rpms-local.list
EOF
        #typeset -F | awk '{print $3}' | grep -v "^main$"
}
 
main()
{
        if [ "$#" -lt 1 ]
        then
                usage
        else
                shift
                $FUNC $*
        fi
}
 
main $*
2025/03/24 15:06

Script bash fonctions en vrac

Voir Fonctions conversion Hexa ASCII

Fonctions récupérées de http://www.trapkit.de/tools/checksec.sh

#! /bin/bash
 
set -euo pipefail
IFS=$' \t\n'
export LC_ALL=C
 
SCRIPT_NAME=$(basename "$0")
readonly SCRIPT_NAME
SCRIPT_DIR=$(readlink -m "$(dirname "$0")")
readonly SCRIPT_DIR
 
# Launch this script as root
if [ $EUID != 0 ]; then
    sudo "$0" "$@"
    exit $?
fi
 
[ -r /etc/default/plop ] && . /etc/default/plop
 
# check if command exists
command_exists() { type $1  > /dev/null 2>&1; }
 
command_exists() {
	command -v "$1" >/dev/null 2>&1 || (
		echo "I require $1 but it's not installed. Aborting." >&2
		exit 127
	)
}
 
for COMMAND in "nova" "glance" "dmidecode" "tr"
do
  command_exists "${COMMAND}"
done
 
 
exit_si_erreur() {
    if [ $1 != 0 ]
    then
        echo "Sortie en erreur."
        exit 1
    fi
}
 
# plop ; exit_si_erreur $?
 
get_mountpoint() { df -l --output=target "$1" |sed -e "1d" ;}
 
 
# check if directory is empty
dir_is_empty() {
  if [ -z "$(ls -A $1)" ]
  then
    return 0
  else
    return 1
  fi
}
 
isNonEmptyStr() { echo "$@" | grep -q -v -e "^$" ;}
 
is_empty_var() {
        local var
        var=$1
        if [[ "${!var:-}" == "" ]]
}
 
is_valid_value_var() {
  # Syntax exemple :
  # is_valid_value_var BOOL y n && echo "VAR 'BOOL' is 'y' or 'n'"
  # is_valid_value_var NUM 1 2 3 || echo "VAR 'NUM' is not 1, 2, or 3"
  local var=$1
  shift
  for value in "$@"
  do
      if [ "${!var-}" == "$value" ]
      then
          return 0 # TRUE
      fi
  done
  return 1 # FALSE
}
 
 
 
 
isDevMounted() { findmnt --source "$1" >/dev/null;} #device only
isPathMounted() { findmnt --target "$1" >/dev/null;} #path   only
isMounted() { findmnt          "$1" >/dev/null;} #device or path
is_mount() { findmnt -M "$1" >/dev/null ;}
# Voir aussi la commande "mountpoint"
 
# check user privileges
root_privs() {
  if [ "$(/usr/bin/id -u)" -eq 0 ]
  then
    return 0
  else
    return 1
  fi
}
 
# Require that this runs as root.
[ "$UID" -eq 0 ] || exec sudo "$0" "$@"
 
# check if input is numeric
isNumeric() { echo "$@" | grep -q -v -e "[^0-9]" ; }
 
# check if input is a string
isString() { echo "$@" | grep -q -v -e "[^A-Za-z]" ; }
 
# check if file exist
file_exist() {
  if [ $# -ne 1 ]
  then
      echo "illegal number of parameters"
      exit 2
  fi
  [ -e "$1" ]
}
 
#
return_only_files_exists() { ls -1 "$@" 2>/dev/null ;}
 
 
if !(isString "$2")
then
    printf "\033[31mError: Please provide a valid process name.\033[m\n\n"
    exit 1
fi
 
if ! command -v zgrep &> /dev/null
then
        zgrep() {
                zcat "$2" | grep "$1"
        }
fi
 
check_device() {
	if [ -c "$1" ]
        then
		wrap_good "$1" 'present'
	else
		wrap_bad "$1" 'missing'
		EXITCODE=1
	fi
}
 
strip_comment() { grep -Ev -e '^\s+#|^#' - ;}
 
abs() {
        local -i VAL=$1
        echo "${VAL#-}"
}
 
 
calc_sum() { awk '{s+=$1} END {printf "%.0f", s}' "$*" ;}
 
 
mk_calc() { awk "BEGIN { print $* }"; }
# ex : mk_calc 7.5/3.2 => 2.34375
# Voir aussi expr : CACHE_USED=$( expr \( $CACHE_USED \* 1024 \) )
 
# A helper to make sure that Chrome is linked correctly
function installation_status() {
    google-chrome-stable --version > /dev/null 2>&1
    [ $? -eq 0 ]
}
 
 
############ Source : https://github.com/danguita/scripts/blob/master/kickstart/kickstart-debian.sh
 
say() {
  printf "\n[$(date --iso-8601=seconds)] %s\n" "$1"
}
 
# shellcheck disable=SC2317
confirm() {
  while true; do
    read -r -p "$1 (y/[n]): " answer
    case $answer in
      [Yy]* ) return 0; break;;
      [Nn]* ) return 1; break;;
      "" ) return 1; break;;
      * ) echo "Please answer yes or no.";;
    esac
  done
}
 
install_package() {
  sudo apt install --no-install-recommends -y "$@"
}
 
#########
 
quote () {
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}
 
 
dequote () {
    eval printf %s "$1" 2> /dev/null
}

get_dev.sh

#! /bin/bash
 
# Respond to the question : if a new file is created, this will be on which block device ?
# Input arg 1 : path (file)
# Outpout     : path (block device)
 
set -euo pipefail
IFS=$' \t\n'
export LC_ALL=C
 
NEW_FILE="$1"
 
is_regular_file() {
    [[ -f $1 ]]
}
 
# check if directory exists
is_dir() {
    [[ -d $1 ]]
}
 
get_parent_dir() {
        local CHEMIN="$1"
        while ! "$(dir_exists "$CHEMIN")"
        do
                CHEMIN=$(dirname "$CHEMIN")
        done
        echo "$CHEMIN"
}
 
get_device() { df -lP "$(get_parent_dir "$NEW_FILE")" |awk 'NR==2{print $1}' }
 
get_device "$(get_parent_dir "$NEW_FILE")"

A la place de

dir_exists /tmp/plop || mkdir -p /tmp/plop

Il est préférable de faire d'uuliser la commande install

install -d /tmp/plop

Faire une division

echo $(( 10 / 3 ))
echo $(( VAR / 3 ))
expr 10 / 3
 
calc() { awk "BEGIN { print ""$*"" }" }
my_command || { echo 'my_command failed' ; exit 1; }

Bash Colors
source : https://github.com/moby/moby/blob/master/contrib/check-config.sh

color() {
	local codes=()
	if [ "$1" = 'bold' ]; then
		codes=( "${codes[@]}" '1' )
		shift
	fi
	if [ "$#" -gt 0 ]; then
		local code=
		case "$1" in
			# see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
			black) code=30 ;;
			red) code=31 ;;
			green) code=32 ;;
			yellow) code=33 ;;
			blue) code=34 ;;
			magenta) code=35 ;;
			cyan) code=36 ;;
			white) code=37 ;;
		esac
		if [ "$code" ]; then
			codes=( "${codes[@]}" "$code" )
		fi
	fi
	local IFS=';'
	echo -en '\033['"${codes[*]}"'m'
}
 
wrap_color() {
	text="$1"
	shift
	color "$@"
	echo -n "$text"
	color reset
	echo
}
 
wrap_good() { echo "$(wrap_color "$1" white): $(wrap_color "$2" green)" }
 
wrap_bad() { echo "$(wrap_color "$1" bold): $(wrap_color "$2" bold red)" ; }
 
wrap_warning() { wrap_color >&2 "$*" red ; }
 
error() { printf "${red}!!! %s${reset}\\n" "${*}" 1>&2 ; }
 
failure() {
    local rc=$?
    echo -e "\t[FAILED]"
    return $rc
}
 
success() {
    echo -e "\t[  OK  ]"
    return 0
}
 
# Getpass
read -s password
read -s -p "Password: "
 
get_free_space() {
	local chemin=$1
	local -i free_mb
	free_mb="$(df --output=avail -m "$chemin" | tail -1 | tr -d ' ')"
	echo "$free_mb"
}
 
check_free_space() {
	# check_free_space /tmp/ 200
	# will exit if /tmp/ less than 200MB
	local chemin=$1
	local -i min_free_mb=$2
	if [[ "$(get_free_space "$chemin")" -lt min_free_mb ]]
	then
	  echo ERROR: No space left on device >&2
	  exit 28
	fi
}

Appelle d'une fonction bash depuis un autre shell
Même UID pour deux utilisateurs différents

cat <<EOF | bash -s --
same_uid_for_Utilisateur_and_utilisateur() {
    local -i RET=0
    local -i UID_Utilisateur=$(id -u Utilisateur)
    RET=$(( RET + $? ))
    local -i UID_utilisateur=$(id -u utilisateur)
    RET=$(( RET + $? ))
 
    if [[ (RET -eq 0) && (UID_Utilisateur -ne UID_utilisateur) ]]
    then
        echo "usermod -o -u $(id -u utilisateur) -g $(id -g utilisateur) Utilisateur"
        chown -R utilisateur:utilisateur /var/opt/plop
        usermod -o -u $(id -u utilisateur) -g $(id -g utilisateur) Utilisateur
    fi
 
    exit
}
 
same_uid_for_Utilisateur_and_utilisateur
EOF

Variables

SCRIPTPATH=$(dirname "$(realpath "$0")")

http://linuxfr.org/users/srb/journaux/waitend-executer-une-commande-apres-une-autre-deja-lancee

Si la commande waitpid n'est pas présente (util-linux-extra)

waitpid() {
        while ps -p $1 >/dev/null ; 
        do
                sleep 5
        done
        shift
        "$@"
}

Strip char / trim ⇒ utiliser xargs ex :

load5=$(echo $UPTIME | awk -F, '{print $5}' | xargs)

Gestion des logs

#!/bin/bash
NAME=plop
LOG=/var/log/$NAME/$NAME.log
 
exec >>$LOG 2>&1
exec &> >(tee -i /var/log/stackscript.log)

Gestion des erreurs

#! /bin/bash
 
# to combine `set -e` (same as: `set -o errexit`) with an ERR trap
set -eE  # same as: `set -o errexit -o errtrace`
 
err_report()
{
    echo "Error on line $1"
}
 
trap 'err_report $LINENO' ERR
 
echo hello | grep foo  # This is line number 9

Source : https://unix.stackexchange.com/questions/39623/trap-err-and-echoing-the-error-line

Exécution à la sortie

trap 'rm -f "$TMP_INV_INI"' EXIT ERR

ou encore

trap '[ "$?" -eq 61 ] || exit 61' 0

No sigterm terminate

#!/bin/bash
trap '' SIGTERM

Utilisation d'aliases dans un script shell

shopt -s expand_aliases
source ~/.bash_aliases

Autres

How to make sure only one instance of a bash script runs ?

if [ $(pidof -x $0| wc -w) -gt 2 ]; then
    echo "More than 1"
    exit
fi

Note : NOP en bash :

true
# We use this to print to the terminal when the context
# of STDOUT is something other than the pty.
declare -r TTY="$(tty)"
 
printf $'%s %s\n' "${method}" "${path}" >${TTY}
printf $'HTTP/1.1 %s %s\r\n' "${status:?}" "${msg:?}" | tee ${TTY}

Bash variable Substitution

Supprimer une extention de fichier

$ VAR="plop.txt"
$ echo ${VAR%.txt}
plop
$ var=sd_feeef_efe_g
$ echo "${var#?*_}"
feeef_efe_g
$ var=toto-tt-ll
$ echo "${var//-/_}"
toto_tt_ll
$ echo "${a/-/_}"
toto_tt-ll

Case upper lower majuscule minuscule

x="Hello"
echo $x  # HELLO
 
y=${x,,}
echo $y  # hello
 
z=${y^^}
echo $z  # HELLO

Dernier caractère d'une chaine

echo "${str: -1}"
 
# ou
 
echo ${str:0-1}

Renommer en supprimant un prefix

for fic in *.j2 ; do mv "$fic" "${fic#PREFIX_}" ; done

#!/bin/bash
SCRIPT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 
${SCRIPT_PATH}/sds_run.sh portal

negate() {
    if [[ $# -eq 0 ]]; then
        echo "ERROR. ENOSYS Function not implemented" >&2
        return 38
    else
        # ! "${@}"
        "${@}" && return 1 || return 0
    fi
}
$ negate true ; echo $?
1

$ negate false ; echo $?
0

$ true | negate ; echo $?
ERROR. ENOSYS Function not implemented
38

$ false | negate ; echo $?
ERROR. ENOSYS Function not implemented
38

Voir aussi :

  • PIPESTATUS
  • pipefail
2025/03/24 15:06
blog.txt · Dernière modification : de 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki