Table des matières
- 2026:
- 2025:
4 billet(s) pour septembre 2026
| Notes HTTP Strict Transport Security - HSTS | 2026/09/18 11:04 | Jean-Baptiste |
| Notes GNU Linux GPU carte graphiques | 2026/09/08 15:49 | Jean-Baptiste |
| Notes GNU Linux graphique | 2026/09/08 15:42 | Jean-Baptiste |
| Notes urlencoding - passer des mots de passe en HTTPS | 2026/09/03 17:58 | Jean-Baptiste |
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
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
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'
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 $*
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
