mirror of https://framagit.org/kyodev/kyopages.git
3956 lines
168 KiB
Bash
Executable File
3956 lines
168 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
version=2.55.0
|
||
date="5/12/2017"
|
||
projet="simpledeb"
|
||
contact="IRC freenode ##sdeb ou https://framagit.org/kyodev/kyopages/issues/"
|
||
script="getInfo"
|
||
|
||
##### license LPRAB/WTFPL
|
||
# auteur: simpledeb
|
||
# contributeurs: kyodev, saiqui, naguam, agentcobra, amilcar
|
||
#####
|
||
|
||
# détecte architecture système, assign $fu_archi: 32bits, i686 | 64bits, amd64 (x86_64)
|
||
# return 1 on unknown architecture
|
||
# remarque, debian: dpkg --print-architecture affiche i386
|
||
f__architecture(){ # 2/12/2017
|
||
case "$(uname -m)" in
|
||
amd64 | x86_64 )
|
||
fu_archi="64bits, amd64 (x86_64)";;
|
||
i?86 | x86 )
|
||
fu_archi="32bits, i686";;
|
||
* )
|
||
case "$(getconf LONG_BIT)" in
|
||
64 )
|
||
fu_archi="64bits, amd64 (x86_64)";;
|
||
32 )
|
||
fu_archi="32bits, i686";;
|
||
*)
|
||
return 1
|
||
esac ;;
|
||
esac
|
||
}
|
||
|
||
f__color(){ # 08/10/2017
|
||
YELLOW=$(tput setaf 3) # question
|
||
GREEN=$(tput setaf 2) # ok
|
||
BLUE=$(tput setaf 4) # info
|
||
RED=$(tput setaf 1) # alerte
|
||
STD=$(tput sgr0) # retour normal
|
||
MAGENTA=$(tput setaf 5)
|
||
CYAN=$(tput setaf 6)
|
||
BOLD=$(tput bold)
|
||
ITAL=$(tput sitm)
|
||
SOUL=$(tput smul)
|
||
}
|
||
|
||
# $1=oui|non&[-tx] réponse par défaut & -tx=timeout, $2=message question, return 0 pour oui, 1 pour non
|
||
f__dialog_oui_non(){ # 5/12/2017
|
||
local reply param
|
||
[[ "$1" =~ -t[0-9]{1,2} ]] && param="$(sed -En 's/.*(-t[0-9]{1,2}).*/\1/p' <<< $1)"
|
||
echo -en "$BLUE$2$STD"
|
||
[[ "$1" =~ oui ]] && echo -n " [O/n] " || echo -n " [o/N] "
|
||
if [ "$param" ]; then
|
||
read -t2 reply
|
||
else
|
||
read reply
|
||
fi
|
||
if [ -z "$reply" ]; then
|
||
[[ "$1" =~ oui ]] && reply="oui" || reply="non"
|
||
fi
|
||
echo
|
||
if [[ ${reply,,} =~ ^ou?i?$ ]]; then return 0; else return 1; fi
|
||
}
|
||
|
||
# affichage $1 en rouge, $1++ optionnels en bleu, sortie script sur erreur, log $1 si $opType=upgrade
|
||
f__error(){ # 4/12/2017
|
||
local depart=1 i
|
||
|
||
echo -e "\n$RED $script $version, erreur critique: $1 $STD"
|
||
for (( i=2 ; i<=$# ; i++ )); do
|
||
echo -e " $BLUE${!i}$STD"
|
||
done
|
||
echo
|
||
if [ "$opType" == "upgrade" ]; then f__log "$script $version: $1"; fi
|
||
exit 1
|
||
}
|
||
|
||
# affichage des paramètres en bleu, si $1=raw pas de ligne vide à la fin, si $1=log alors uniquement $2 logué
|
||
f__info(){ # 15/10/2017
|
||
local depart=1 i
|
||
|
||
if [ "$1" == "raw" ] || [ "$1" == "log" ]; then depart=2; fi
|
||
[ "$1" == "log" ] && f__log "$(sed -E 's/\\t//;s/\\n// ' <<< $2 | xargs )"
|
||
for (( i=$depart ; i<=$# ; i++ )); do
|
||
echo -e " $BLUE${!i}$STD"
|
||
done
|
||
[ "$1" == raw ] || echo
|
||
}
|
||
|
||
# log spécifique, fichier log limité à 10000 octets, $1 message à loguer
|
||
f__log(){ # 4/12/2017
|
||
if [ -w "$scriptLogs" ]; then
|
||
if [ "$(stat -c %s $scriptLogs)" -ge "10000" ]; then
|
||
echo "$(date +%Y%m%d\ %H%M%S) $1" &>/dev/null > "$scriptLogs"
|
||
else
|
||
echo "$(date +%Y%m%d\ %H%M%S) $1" &>/dev/null >> "$scriptLogs"
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# test dépendances/paquets, $1 liste commande[>paquet] (ex: killall>psmisc)
|
||
# si manque, return 1 & info commandes manquantes, si debian proposition paquet à installer
|
||
# si $2=debOnly et si paquets manquants: return 1 et $debOnlyAbsent ( $1=liste paquets )
|
||
# si $2=debOnly et si paquets présent: return 0 et $debOnlyPresent ( $1=liste paquets )
|
||
# attention priorité $debOnlyAbsent sur $debOnlyPresent
|
||
f__requis(){ # 4/12/2017
|
||
local dependsMissing packagesMissing command package ireq compteur pluriel
|
||
|
||
unset debOnlyAbsent debOnlyPresent
|
||
for ireq in $1; do
|
||
command="$(cut -d '>' -f 1 <<< $ireq)"
|
||
package="$(cut -d '>' -f 2 <<< $ireq)"
|
||
if [ "$2" == "debOnly" ]; then
|
||
if type -p "dpkg" &>/dev/null ; then # package only et debian
|
||
LC_ALL=C dpkg --get-selections | grep -qE "^$package[[:space:]]+install" \
|
||
&& debOnlyPresent+="$package " || debOnlyAbsent+="$package "
|
||
fi
|
||
elif ! type -p "$command" &>/dev/null ; then
|
||
dependsMissing+="$command "
|
||
packagesMissing+="$package "
|
||
fi
|
||
done
|
||
[ "$debOnlyAbsent" ] && debOnlyAbsent="$(xargs <<< $debOnlyAbsent)" # trim début & fin
|
||
[ "$debOnlyPresent" ] && debOnlyPresent="$(xargs <<< $debOnlyPresent)" # trim début & fin
|
||
[ "$debOnlyAbsent" ] && return 1
|
||
[ "$debOnlyPresent" ] && return 0
|
||
if [ "$dependsMissing" ]; then
|
||
compteur="$(wc -w <<< $dependsMissing)"
|
||
[ "$compteur" -gt "1" ] && pluriel="s" || unset pluriel
|
||
if [ -e /etc/debian_version ]; then
|
||
f__info "$RED""erreur critique: $compteur paquet"$pluriel" manquant"$pluriel": $STD$BOLD$dependsMissing" \
|
||
"\n vous devriez exécuter:$GREEN apt install $packagesMissing"
|
||
else
|
||
f__info "$RED""erreur critique: $compteur commande"$pluriel" manquante"$pluriel": $STD$BOLD$dependsMissing"
|
||
fi
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# $1=cmd si $2: nb de tentatives pour s'identifier, sinon 2 tentatives par défaut, suppose bash existant
|
||
f__sudo(){ # 4/12/2017
|
||
local nb=2 sudo isudo toBash
|
||
|
||
[ $( type -p bash 2>/dev/null ) ] && toBash="$( type -p bash )" || return 2
|
||
# sudo --shell bash équivalent su ?
|
||
if sudo -v &>/dev/null && [ $EUID -ne 0 ] ; then
|
||
sudo="sudo su --shell $toBash --preserve-environment -c "
|
||
else
|
||
sudo="su --shell $toBash --preserve-environment -c "
|
||
fi
|
||
[ "$2" ] && nb="$2"
|
||
for (( isudo=1 ; isudo<="$nb" ; isudo++ )); do
|
||
$sudo " $1"
|
||
[ "$?" == 0 ] && break
|
||
[ "$isudo" == "$nb" ] && return 1
|
||
done
|
||
}
|
||
|
||
# conversion human, source ko, $1=nombre à convertir, affiche ko ou Mo ou Go, ! dépendance gawk
|
||
f__unit_human(){ # 5/12/2017
|
||
echo -n "$( gawk ' {
|
||
if ( $1<1024 ) {unit="ko"; printf "%d%s", $1, unit; exit}
|
||
if ( $1<1024*1024 && $1>=1024 ) {unit="Mo"; printf "%d%s", $1/1024, unit}
|
||
else {unit="Go"; printf "%.1f%s", $1/1024/1024, unit}
|
||
}' <<< $1 )"
|
||
}
|
||
|
||
# test wget, $1=url à tester, sortie du script (même si url testée ok) avec affichage erreur ou ok
|
||
# si $2=print affiche url testée & entêtes http & location, return 0
|
||
# si $2=loc affiche seulement location, return 0
|
||
# si $2=test return 0 si ok, return 1 si KO
|
||
f__wget_test(){ # 5/12/2017
|
||
local file_test_wget retourWget retourHttp location
|
||
|
||
file_test_wget="/tmp/testWget-$$-$RANDOM"
|
||
wget -Sq --timeout=10 --user-agent="$user_agent" --spider --save-headers "$1" &>"$file_test_wget"
|
||
retourWget="$?"
|
||
[ "$retourWget" == 1 ] && retourWget="1: code erreur générique"
|
||
[ "$retourWget" == 2 ] && retourWget="2: parse erreur (ligne de commande?)"
|
||
[ "$retourWget" == 3 ] && retourWget="3: erreur Entrée/sortie fichier"
|
||
[ "$retourWget" == 4 ] && retourWget="4: défaut réseau"
|
||
[ "$retourWget" == 5 ] && retourWget="5: défaut vérification SSL"
|
||
[ "$retourWget" == 6 ] && retourWget="6: défaut authentification"
|
||
[ "$retourWget" == 7 ] && retourWget="7: erreur de protocole"
|
||
[ "$retourWget" == 8 ] && retourWget="8: réponse serveur en erreur"
|
||
retourHttp="$( grep -i 'HTTP/' "$file_test_wget" | tr -d '\n' | xargs )"
|
||
location="$( grep -i 'location' $file_test_wget | xargs )"
|
||
if [ "$2" == "test" ]; then
|
||
rm "$file_test_wget" 2>/dev/null
|
||
# spécial maintenance frama.link, pas de redirection sur page status framalink
|
||
[ "$( grep -c '303' <<< $retourHttp )" -ne 0 ] && return 1 # 303 See Other
|
||
[ "$retourWget" == "0" ] && return 0 || return 1
|
||
fi
|
||
if [ "$2" == "print" ]; then
|
||
if [ "$retourWget" != "0" ]; then
|
||
echo "erreur wget: $RED$retourWget"
|
||
echo -e "$BLUE $1$STD\t$RED $retourHttp"
|
||
else
|
||
echo -e "$BLUE $1$STD\t$GREEN $retourHttp"
|
||
fi
|
||
echo "$STD"
|
||
fi
|
||
if [ "$2" == "print" ] || [ "$2" == "loc" ]; then
|
||
[ "$location" ] && echo -n "$YELLOW $location" || echo -n "$YELLOW no location"
|
||
echo "$STD"
|
||
rm "$file_test_wget" 2>/dev/null
|
||
return 0
|
||
fi
|
||
if [ "$retourWget" != "0" ]; then
|
||
rm "$file_test_wget" 2>/dev/null
|
||
# f__error "wget, $retourWget" "$1" "$YELLOW$retourHttp" "$location"
|
||
echo -e "$RED erreur wget, $retourWget \n $1 \n $YELLOW$retourHttp \n $location$STD"
|
||
fi
|
||
if [ "$(grep -c '200' <<< $retourHttp)" -ne 0 ]; then
|
||
echo -e "$GREEN\ntout est ok, réessayer$STD\n"
|
||
fi
|
||
rm "$file_test_wget" 2>/dev/null
|
||
exit 0
|
||
}
|
||
|
||
# $1='-l' comptage ligne dans variable $2, affiche quantité
|
||
# $1='-w' comptage dans variable $2 des mots
|
||
# $1='-wv' comptage dans variable $2, des mots $3, affiche quantité
|
||
# f__wcv -l $var ; f__wcv -w $var ; f__wcv -wv $var "mot"
|
||
f__wcv(){ # 09/11/2017
|
||
[[ "$1" =~ -l|-wv|-w ]] || display="erreur f__wcv \$1 ($1) incorrect \n"
|
||
[ "$1" == "-l" ] && echo "$2" | grep -cEv '^[[:space:]]*$' # (wc -l compterait 1 pour une variable vide)
|
||
[ "$1" == "-w" ] && echo "$(xargs <<< $2) " | grep -o " " | grep -c . # echo $(( $(grep -c .)+1 ))
|
||
[ "$1" == "-wv" ] && echo "$2" | grep -o "$3" | grep -c .
|
||
}
|
||
|
||
# test wget, $1=url à tester, sortie du script (même si url testée ok) avec affichage erreur ou ok
|
||
# si $2=print affiche url testée & entêtes http & location, return 0
|
||
# si $2=loc affiche seulement location, return 0
|
||
# si $2=test return 0 si ok, return 1 si KO
|
||
f__wget_test(){ # 5/12/2017
|
||
local file_test_wget retourWget retourHttp location
|
||
|
||
file_test_wget="/tmp/testWget-$$-$RANDOM"
|
||
wget -Sq --timeout=10 --user-agent="$user_agent" --spider --save-headers "$1" &>"$file_test_wget"
|
||
retourWget="$?"
|
||
[ "$retourWget" == 1 ] && retourWget="1: code erreur générique"
|
||
[ "$retourWget" == 2 ] && retourWget="2: parse erreur (ligne de commande?)"
|
||
[ "$retourWget" == 3 ] && retourWget="3: erreur Entrée/sortie fichier"
|
||
[ "$retourWget" == 4 ] && retourWget="4: défaut réseau"
|
||
[ "$retourWget" == 5 ] && retourWget="5: défaut vérification SSL"
|
||
[ "$retourWget" == 6 ] && retourWget="6: défaut authentification"
|
||
[ "$retourWget" == 7 ] && retourWget="7: erreur de protocole"
|
||
[ "$retourWget" == 8 ] && retourWget="8: réponse serveur en erreur"
|
||
retourHttp="$( grep -i 'HTTP/' "$file_test_wget" | tr -d '\n' | xargs )"
|
||
location="$( grep -i 'location' $file_test_wget | xargs )"
|
||
if [ "$2" == "test" ]; then
|
||
rm "$file_test_wget" 2>/dev/null
|
||
# spécial maintenance frama.link, pas de redirection sur page status framalink
|
||
[ "$( grep -c '303' <<< $retourHttp )" -ne 0 ] && return 1 # 303 See Other
|
||
[ "$retourWget" == "0" ] && return 0 || return 1
|
||
fi
|
||
if [ "$2" == "print" ]; then
|
||
if [ "$retourWget" != "0" ]; then
|
||
echo "erreur wget: $RED$retourWget"
|
||
echo -e "$BLUE $1$STD\t$RED $retourHttp"
|
||
else
|
||
echo -e "$BLUE $1$STD\t$GREEN $retourHttp"
|
||
fi
|
||
fi
|
||
if [ "$2" == "print" ] || [ "$2" == "loc" ]; then
|
||
[ "$location" ] && echo -n "$YELLOW $location" || echo -n "$YELLOW no location"
|
||
echo "$STD"
|
||
rm "$file_test_wget" 2>/dev/null
|
||
return 0
|
||
fi
|
||
if [ "$retourWget" != "0" ]; then
|
||
rm "$file_test_wget" 2>/dev/null
|
||
# f__error "wget, $retourWget" "$1" "$YELLOW$retourHttp" "$location"
|
||
echo -e "$RED erreur wget, $retourWget \n $1 \n $YELLOW$retourHttp \n $location"
|
||
fi
|
||
if [ "$(grep -c '200' <<< $retourHttp)" -ne 0 ]; then
|
||
echo -e "$GREEN\ntout est ok, réessayer\n$STD"
|
||
fi
|
||
rm "$file_test_wget" 2>/dev/null
|
||
exit 0
|
||
}
|
||
|
||
# $1=commande à tester, return localisation cmd si existe, return 1 si absent avec aucun message (à là debian)
|
||
# pour un test concis genre [ "$(f__which $cmd)" ] && echo "$cmd existe"
|
||
# utilisation `type -p` pour le test, pour une bonne portabilité
|
||
f__which(){ # 27/11/2017
|
||
if type -p "$1" &>/dev/null ; then
|
||
echo $( type -p $1 2>/dev/null ) # équivalent: command -v
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
f_affichage(){ # 2/12/2017
|
||
f__color
|
||
local affichage_text=" _ ___ __
|
||
__ _ ___| |_|_ _|_ __ / _| ___
|
||
/ _' |/ _ \ __|| || '_ \| |_ / _ \
|
||
| (_| | __/ |_ | || | | | _| (_) |
|
||
\__, |\___|\__|___|_| |_|_| \___/
|
||
|___/ "
|
||
clear
|
||
echo -e "$BLUE$affichage_text\n$YELLOW version $version - $date$STD\n"
|
||
}
|
||
|
||
# $1 type de titre var|cmd|sans|+:text|+:vide, $2 variable à afficher [$3 titre] [$4 commentaire]
|
||
# $1: cmd->`titre`, var->**titre**, sans: pas de titre
|
||
# :text ajouté, affiche le text en liste (avec puce)
|
||
# :vide bypass le test de contenu $2, affiche 'vide', si besoin, en liste
|
||
# passage en paramètre VARIABLE et pas $variable
|
||
# un test si variable $2 est vide est fait sauf ':vide'
|
||
# un test si variable $2 contient 'nofile' (non trouvé par f_grep_file)
|
||
# f_di "variable" "type" "titre" "commentaire"
|
||
f_di(){ # 2/12/2017
|
||
local display='' toDisplay
|
||
|
||
[ "$text" ] && echo -en "$text" >> "$fileOutput" # flush, avant fonction, de $text parent
|
||
unset text
|
||
|
||
toDisplay="$2"
|
||
[[ "$2" || "$1" =~ :vide ]] || return 0 # test si contenu dans $2
|
||
# traitement ligne de titre
|
||
[ "$toDisplay" ] || toDisplay="vide" # cas si :vide
|
||
[[ "$1" =~ sans|var|cmd ]] || display=" **⚡ erreur f_di \$1 ($2 $3) ⚡** \n" # test $1 valide
|
||
[[ "$1" =~ "var" ]] && display="**$3**" # type var, titre en gras
|
||
[[ "$1" =~ "cmd" ]] && display="\`$3\`" # type cmd, titre entre backtick
|
||
[ "$4" ] && display+="$spc5( $4 )" # +$4 en gras avec 5 espaces insécables avant
|
||
[ "$1" != "sans" ] && display+=" \n"
|
||
[[ "$1" == "sans" && "$3$4" ]] && display+=" \n"
|
||
# traitement contenu
|
||
if [ "$toDisplay" == "nofile" ]; then # nofile renvoyé par f_grep
|
||
display+="\n* fichier $2 non trouvé \n"
|
||
elif [[ "$1" =~ :text || "$toDisplay" == "vide" ]]; then
|
||
display+="\n* $toDisplay \n"
|
||
else
|
||
display+='``` \n'
|
||
display+="$toDisplay \n"
|
||
display+='``` \n'
|
||
fi
|
||
echo -en "$display\n" >> "$fileOutput" # flush fonction
|
||
}
|
||
|
||
# $1 variable à afficher en alerte/info, [$2 alert|info] type de message, alert par défaut
|
||
# un test si variable $1 est vide ou non est fait
|
||
f_dspl_alrt(){ # 21/11/2017
|
||
[ "$1" ] || return 0 # test si contenu dans $1
|
||
local display type
|
||
# flush, avant fonction, de $text parent
|
||
[ "$text" ] && echo -en "$text\n" >> "$fileOutput"
|
||
unset text
|
||
|
||
[[ "$2" =~ info ]] && type="info"
|
||
[[ "$2" =~ alert ]] && type="alert"
|
||
[ "$2" ] || type="alert" # alert par défaut
|
||
[ "$type" == "alert" ] && display="> ↯ $1 \n\n"
|
||
[ "$type" == "info" ] && display=" ☛ $1 \n\n"
|
||
echo -en "$display\n" >> "$fileOutput" # flush fonction
|
||
}
|
||
|
||
# conversion markdown pour affichage en console, $1 file à parser, [$2=marge] margin left 2 espaces
|
||
# tout en bash regex par défaut non-greedy (non gourmand) comme sed ou gawk
|
||
# contrainte markdown:
|
||
# l'italique avec _ ou * n'est pas géré, trop d'interférences potentielles
|
||
# liste niveau2: 3 ou 4 caractères, niveau3: 6 ou 8 caractères, puce * ou -
|
||
f_dspl_md(){ # 3/12/2017
|
||
local display display2 ligne margin
|
||
if [ ! -f "$1" ]; then
|
||
f__info "pas de rapport à afficher, vous devez lancer une analyse auparavant:" \
|
||
"$GREEN$script -l$BLUE ou afficher l'aide $GREEN$script -h"
|
||
return 0
|
||
fi
|
||
if [ "$(stat -c %s $1)" -gt "100000" ]; then # si taille en octets > 100ko pager
|
||
pager "$1" || less "$1" || more "$1"
|
||
return
|
||
fi
|
||
[ "$2" == "marge" ] && margin=" "
|
||
display=$(< $1)
|
||
# code
|
||
display=${display//\`\`\`/------------} # transforme ``` en ---, plus visibles
|
||
# traitement par lignes, à là sed, obligatoire pour les titres #
|
||
# plus simple pour les multi-patterns, sinon matches multilignes délicats à gérer en cas d'impairage
|
||
IFS=$'\n' # normalement inutile
|
||
display=${display//\\/\\\\} # echappement des antislash, utile pour efiboot
|
||
while read ligne; do
|
||
ligne=${ligne//\\/\\\\} # re echappement des antislash, utile pour efiboot, méthode bourrin, sans comprendre le pourquoi
|
||
# # TITRE 1 red
|
||
[[ "$ligne" =~ ^(#[^#].*)$ ]] && ligne="\x1B[31m"${BASH_REMATCH[1]}"\x1B(B\x1B[m"
|
||
# ## TITRE 2 blue
|
||
[[ "$ligne" =~ ^(#{2}[^#].*)$ ]] && ligne="\x1B[34m"${BASH_REMATCH[1]}"\x1B(B\x1B[m"
|
||
# ### TITRE 3 green
|
||
[[ "$ligne" =~ ^(#{3}[^#].*)$ ]] && ligne="\x1B[32m"${BASH_REMATCH[1]}"\x1B(B\x1B[m"
|
||
# #### TITRE 4 yellow
|
||
[[ "$ligne" =~ ^(#{4}[^#].*)$ ]] && ligne="\x1B[33m"${BASH_REMATCH[1]}"\x1B(B\x1B[m"
|
||
# interne message alert, red
|
||
[[ "$ligne" =~ ( ↯ .*)$ ]] && ligne="\x1B[31m"${BASH_REMATCH[1]}"\x1B(B\x1B[m"
|
||
# interne message indo, green
|
||
[[ "$ligne" =~ ( ☛ .*)$ ]] && ligne="\x1B[32m"${BASH_REMATCH[1]}"\x1B(B\x1B[m"
|
||
# **gras**
|
||
while [[ "$ligne" =~ (.*)\*{2}(.*)\*{2}(.*) ]]; do
|
||
ligne=${BASH_REMATCH[1]}'\x1B[1m'${BASH_REMATCH[2]}'\x1B(B\x1B[m'${BASH_REMATCH[3]}
|
||
done
|
||
# ` backtick en italique
|
||
while [[ "$ligne" =~ (.*)\`([^\`].*)\`(.*) ]]; do
|
||
ligne=${BASH_REMATCH[1]}'\x1B[3m'${BASH_REMATCH[2]}'\x1B(B\x1B[m'${BASH_REMATCH[3]}
|
||
done
|
||
# puces niveau 1
|
||
ligne=${ligne/#\*[^*]/• }
|
||
ligne=${ligne/#-[^-]/• }
|
||
# puces niveau 2
|
||
[[ "$ligne" =~ ^([[:space:]]{3,4})\*(.*)$ ]] && ligne=${BASH_REMATCH[1]}'► '${BASH_REMATCH[2]}
|
||
[[ "$ligne" =~ ^([[:space:]]{3,4})-(.*)$ ]] && ligne=${BASH_REMATCH[1]}'► '${BASH_REMATCH[2]}
|
||
# puces niveau 3
|
||
[[ "$ligne" =~ ^([[:space:]]{6,8})\*(.*)$ ]] && ligne=${BASH_REMATCH[1]}'◾ '${BASH_REMATCH[2]}
|
||
[[ "$ligne" =~ ^([[:space:]]{6,8})-(.*)$ ]] && ligne=${BASH_REMATCH[1]}'◾ '${BASH_REMATCH[2]}
|
||
display2+="$margin""$ligne\n"
|
||
done <<< "$display"
|
||
IFS="$IFS_INI"
|
||
echo -e "$display2"
|
||
}
|
||
|
||
# $1=liste fichier(s) à grepper, [$2]: N &| nofile &| novide &| ligneVide &| date &| commentXY
|
||
# si aucun fichier dans la liste retour: 'nofile|vide|inexistant'
|
||
# /!\ protéger les chemins avec " (surtout si plusieurs chemins ou joker)
|
||
# option largeur, chiffres AU DÉBUT!
|
||
# option 'novide' pas d'indication vide
|
||
# option 'notitre' pas d'énumération de fichier greppé (destiné à un seul fichier)
|
||
# option 'noinexist' pas de titre si fichier inexistant
|
||
# option 'lignevide', pas de suppression des lignes vides
|
||
# option 'date', date de modification du fichier
|
||
# option 'commentXY', OPTION FINALE! commentaire supplémentaire à filtrer, ex: comment//
|
||
# ex. cumul option: "10 novide nofile lignevide" (espace obligatoire, pas d'autre séparateur)
|
||
# cmd de base: grep -Ersv '^#|^$' file|dossier "options"
|
||
f_grep_file(){ # 3/12/2017
|
||
local file content display='' motif
|
||
motif="^[[:blank:]]*#"
|
||
[[ ! "$2" =~ lignevide ]] && motif+="|^[[:blank:]]*$"
|
||
[[ "$2" =~ comment ]] && comment=${2##*comment} # on garde les symboles de commentaires à la fin
|
||
[[ "$2" =~ comment ]] && motif+="|^[[:blank:]]*$comment"
|
||
for file in $1; do
|
||
# contenu
|
||
content=$( grep -Ersv "$motif" "$file" 2>&1)
|
||
if [[ "$2" =~ ^[0-9] ]]; then # si $2 contient des chiffres (largeur) en tête, gawk
|
||
largeur=${2%% *}
|
||
content=$(gawk -v larg="$largeur" '
|
||
!/^[[:blank:]]*$/ { printf "%-"larg"s",$1; $1=""; printf "%s\n",$0 } # exclut ligne vide
|
||
' <<< "$content")
|
||
fi
|
||
[ -d "$file" ] && file+='/' # si répertoire, ajout / final, joli
|
||
content=${content//$file} # joli, suppression de $file dans les noms de fichiers entete grep
|
||
# mise en forme
|
||
if [[ ! "$2" =~ notitre ]]; then # titre
|
||
if [ -e "$file" ]; then
|
||
if [[ "$2" =~ "date" ]]; then
|
||
display+=" $file, date de modification: $( date -r $file '+%d/%m/%Y %H:%M %z' ) \n"
|
||
else
|
||
display+=" --- $file \n"
|
||
fi
|
||
elif [[ ! "$2" =~ "noinexist" ]]; then
|
||
if touch -c $file 2>/dev/null ; then
|
||
display+=" --- $file: inexistant"$'\n\n'
|
||
else
|
||
display+=" --- $file: Permission non accordée"$'\n\n'
|
||
fi
|
||
fi
|
||
fi
|
||
if [ "$content" ]; then
|
||
display+="$content"$'\n\n'
|
||
elif [[ ! "$2" =~ novide && -e "$file" ]]; then
|
||
display+=" ‣ vide"$'\n\n'
|
||
fi
|
||
done
|
||
display=${display%%[[:space:]]}
|
||
[ "$display" ] || display="nofile" # si display vide, inscription 'nofile'
|
||
echo -en "$display"
|
||
}
|
||
|
||
f_help(){ # 22/11/2017
|
||
local toDisplay ligne
|
||
toDisplay=(
|
||
"$GREEN ./getInfo$BLUE : exécution normale, rapport markdown de la configuration"
|
||
"$GREEN getInfo$BLUE : script installé dans le système"
|
||
""
|
||
"$STD$BOLD options:$STD$BLUE"
|
||
" -c : (catégorie) menu sélection catégorie d'analyse"
|
||
" -cs : catégorie système -cs : catégorie configuration"
|
||
" -cr : catégorie réseau -ca : catégorie analyse"
|
||
" -h : (help) affichage aide"
|
||
" -j : (journaux) analyse démarrage système, log Xorg, kernel et système, catégorie -ca"
|
||
" -l : (list) afficher le rapport markdown existant"
|
||
" -p : (paste) exporte le rapport markdown existant, durée standard du paste 7 jours"
|
||
""
|
||
" --ip : affiche ip publique (ipv4/ipv6), pas de rapport markdown"
|
||
" --mac : affiche les adresses Mac, pas de rapport markdown"
|
||
" pas de rapport markdown, $RED ROOT$BLUE requis:"
|
||
" --serial : affiche n° série disques, batterie et châssis"
|
||
" --ssid : affiche configurations ssid, infos confidentielles,$RED NetworkManager$BLUE requis"
|
||
""
|
||
" -tn : durée du paste de n jour(s)"
|
||
" -us : upgrade spécial du script (pas de mise à jour automatique, maj du script en place)"
|
||
""
|
||
" -i, --install : installation du script dans le système, root requis"
|
||
" -r, --remove : suppression du script dans le système, root requis"
|
||
" -u, --upgrade : upgrade script installé si maj possible"
|
||
" -v, --version : version du script, en ligne et en cours d'exécution"
|
||
)
|
||
for ligne in "${toDisplay[@]}"; do
|
||
echo -e "$ligne"
|
||
done
|
||
echo -e "$STD\n plus d'infos: $GREEN$urlNotice\n$STD"
|
||
}
|
||
|
||
# f_pr "1|1|2|l1|l2|l3|titre1|titre2|hl|quote|flush" "texte" '[CONDITION test]'
|
||
# $1:
|
||
# 1|2|3 indentation, liste à puce
|
||
# l1|l2|l3 indentation, avec espaces
|
||
# titre1|titre2|titre3
|
||
# quote|hl|flush
|
||
# $2 texte à afficher
|
||
# $3 test éventuel, Si CONDITION ok -> affichage
|
||
# ATTENTION aux éventuelles collision $x dans ce cas:
|
||
# "[ \"$1\" != \"notitre\" ]" ou "[ $1 != notitre ]" (attention au manque de ")
|
||
# flush (f_pr flush) inutile si f_d(x) final
|
||
# $1 type, $2 texte, [$3] test /!\ assigne la variable parent $text
|
||
f_pr(){ # 1/12/2017
|
||
local preline='' line='' endline=" \n"
|
||
|
||
[[ "$1" == 'titre1' ]] && preline="\n# "
|
||
[[ "$1" == 'titre2' ]] && preline="\n## "
|
||
[[ "$1" == 'titre3' ]] && preline="\n### "
|
||
[[ "$1" =~ titre ]] && endline+="\n"
|
||
[[ "$1" == '1' ]] && line="$( sed -E 's/(.*)/* \1 /' <<<$2 )"
|
||
[[ "$1" == '2' ]] && line="$( sed -E 's/(.*)/ * \1 /' <<<$2 )"
|
||
[[ "$1" == '3' ]] && line="$( sed -E 's/(.*)/ * \1 /' <<<$2 )"
|
||
[[ "$1" == 'l1' ]] && line="$( sed -E 's/(.*)/\1/ ' <<<$2 )"
|
||
[[ "$1" == 'l2' ]] && line="$( sed -E 's/(.*)/ \1/ ' <<<$2 )"
|
||
[[ "$1" == 'l3' ]] && line="$( sed -E 's/(.*)/ \1/ ' <<<$2 )"
|
||
[[ "$1" == 'quote' ]] && preline="> "
|
||
[[ "$line" ]] || line="$2" # utilisation $2 sans traitement à faire
|
||
|
||
if [[ "$3" ]]; then
|
||
eval $3 || return 0 # évaluation de la CONDITION, si erreur: sortie
|
||
fi
|
||
|
||
if [[ "$1" == "hl" ]]; then # <hl>
|
||
text+="\n---\n\n"
|
||
elif [[ "$1" ]]; then
|
||
text+="$preline$line$endline" # ligne formatée
|
||
else
|
||
text+="\n" # newline
|
||
fi
|
||
if [[ "$1" == "flush" ]]; then
|
||
echo -en "$text\n" >> "$fileOutput"
|
||
unset text
|
||
fi
|
||
}
|
||
|
||
# [$1=silent], assigne fe_nb_audio, fe_cards_audio
|
||
fi_audio(){ # 1/12/2017
|
||
local cardsAudio cmd_cards version_alsa card_alsa cmd_card_alsa cmt_card_alsa pluriel text
|
||
local mod cmd_mod cmt_mod modules cmd_modules cmt_modules motif imod
|
||
local alert_alsa
|
||
|
||
# devices
|
||
fe_cards_audio=$( figet_lspci "audio" "name" )
|
||
fe_nb_audio=$(f__wcv -l "$fe_cards_audio")
|
||
[ "$1" == "silent" ] && return 0 # pas d"affichage
|
||
[ "$fe_nb_audio" -eq 0 ] && return 0
|
||
###
|
||
# lspci
|
||
cardsAudio=$( figet_lspci "audio" "raw" )
|
||
cmd_cards="lspci -nnv | grep -EiA6 'Audio device|Audio controller'"
|
||
if [ ! -d /proc/asound ] ; then
|
||
alert_alsa="/proc/asound : répertoire inexistant"
|
||
alert_alsa="ALSA n'est pas installé correctement"
|
||
else
|
||
# ALSA
|
||
version_alsa=$( gawk '{
|
||
sub(/Advanced Linux Sound Architecture Driver /,"")
|
||
sub(/Version /,"")
|
||
sub(/.$/,"")
|
||
print $0
|
||
}' /proc/asound/version )
|
||
card_alsa=$( gawk ' { print " "$0 }' /proc/asound/cards )
|
||
[ "$( grep -c '\[.*\]' <<< "$card_alsa" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmd_card_alsa="cat /proc/asound/cards"
|
||
cmt_card_alsa="carte"$pluriel" enregistée"$pluriel""
|
||
# modules alsa
|
||
mod=$( gawk '{ print $2 }' /proc/asound/modules )
|
||
mod=$( sort <<< $mod )
|
||
[ "$( f__wcv -l "$mod" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmd_mod="cat /proc/asound/modules"
|
||
cmt_mod="module"$pluriel" alsa"
|
||
# modules kernel
|
||
for imod in $( sort -u <<< $mod ); do
|
||
modules+=$( gawk '
|
||
/'$imod'/ { printf "%-25s %s %2s %s\n",$1, $2, $3, $4 }
|
||
' <<< $( lsmod ) )$'\n'"------"$'\n'
|
||
motif+="$imod|"
|
||
done
|
||
motif=${motif%|} # suppression | final
|
||
modules=${modules%[[:cntrl:]]------[[:cntrl:]]} # suppression espacement
|
||
[ "$( f__wcv -l "$modules" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmd_modules="lsmod | grep '$motif'"
|
||
cmt_modules="$( f__wcv -l "$modules" ) module"$pluriel" utilisé"$pluriel" *"
|
||
fi
|
||
###
|
||
f_pr titre2 "audio"
|
||
f_pr l "$(sed -E 's/(.*)/**\1** /' <<< $fe_cards_audio)" # en gras
|
||
f_pr
|
||
# lspci -nnv
|
||
f_di cmd "$cardsAudio" "$cmd_cards"
|
||
f_dspl_alrt "$alert_alsa" "alert"
|
||
f_di cmd "$version_alsa" "/proc/asound/version" "driver alsa (Advanced Linux Sound Architecture)"
|
||
f_di cmd "$card_alsa" "$cmd_card_alsa" "$cmt_card_alsa"
|
||
f_di cmd "$mod" "$cmd_mod" "$cmt_mod"
|
||
f_di cmd "$modules" "$cmd_modules" "$cmt_modules"
|
||
}
|
||
|
||
fi_batt(){ # 1/12/2017
|
||
local pluriel
|
||
|
||
[ "$fg_nb_batt" ] || figet_batt
|
||
[[ "$fg_nb_batt" == "-1" || "$fg_nb_batt" -gt 0 ]] || return 0 # pas de batterie
|
||
[ "$fg_nb_batt" -gt 1 ] && pluriel="s" || unset pluriel
|
||
###
|
||
f_pr titre2 "batterie"$pluriel
|
||
f_di sans "$fg_batt"
|
||
}
|
||
|
||
# [$1=silent] (pas d'affichage), assigne $fe_nb_bluez, $fe_cards_bluez
|
||
fi_bluez(){ # 4/12/2017
|
||
local bluez cmd_bluez cmt_bluez mod cmd_mod cmt_mod srch_mod pluriel text
|
||
local alert_na
|
||
|
||
if [ $( f__which hciconfig ) ]; then
|
||
fe_nb_bluez=$( hciconfig name 2>/dev/null ) || alert_na="PB" # stck tempo du retour hciconfig
|
||
fe_cards_bluez=$( grep -Eo '^hci[0-9]+' <<< $fe_nb_bluez )
|
||
fe_nb_bluez=$( grep -c '^hci[0-9].*$' <<< $fe_nb_bluez )
|
||
fe_cards_bluez=${fe_cards_bluez//[[:cntrl:]]/ }
|
||
else
|
||
fe_nb_bluez=0
|
||
fi
|
||
[ "$1" == "silent" ] && return 0
|
||
###
|
||
[ "$alert_na" ] && alert_na="Bluetooth inaccessible, en erreur"
|
||
f_dspl_alrt "$alert_na" "alert"
|
||
[ "$fe_nb_bluez" -eq 0 ] && return 0
|
||
###
|
||
# état
|
||
bluez=$( hciconfig -a )
|
||
[ "$( grep -c '^hci[0-9]' <<< "$card_alsa" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmd_bluez="hciconfig -a"
|
||
cmt_bluez="état périphérique"$pluriel
|
||
# modules
|
||
figet_modules "bluetooth"
|
||
mod="$fg_modules" # modules chargés
|
||
cmd_mod="lsmod | grep -Ew '$fg_modKernel'" # module driver
|
||
[ "$( f__wcv -l "$mod" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_mod="$( f__wcv -l "$mod" ) module"$pluriel" utilisé"$pluriel" *"
|
||
srch_mod=${fg_modMotif//|/ } # fg_modMotif motif de recherche, avec |
|
||
###
|
||
f_pr titre2 "Bluetooth"
|
||
f_di cmd "$bluez" "$cmd_bluez" "$cmt_bluez"
|
||
f_di cmd "$mod" "$cmd_mod" "$cmt_mod"
|
||
f_di var "$srch_mod" "" "* recherche parmi:"
|
||
}
|
||
|
||
fi_conf(){ # 3/12/2017
|
||
local confs toScrut=(
|
||
/etc/sysctl.conf
|
||
'/etc/sysctl.d/*.conf'
|
||
'/etc/hostname' # debian
|
||
/etc/sysconfig/network # fedora?
|
||
/etc/HOSTNAME # suse
|
||
# /etc/os-release # nouveau standard systemd/freedesktop
|
||
/etc/vconsole.conf
|
||
# /etc/locale.conf # voir fi_locale
|
||
'/etc/tmpfiles.d/*.conf'
|
||
'/etc/binfmt.d/*.conf'
|
||
# /etc/machine-id # voir fi-serial
|
||
'/etc/modules-load.d/*.conf' #modules to load at boot time
|
||
/etc/machine-info
|
||
/etc/modprobe.d/*.conf # blacklist modules
|
||
'/etc/systemd/system/*/override.conf' # éditions services
|
||
)
|
||
|
||
confs=$( f_grep_file "${toScrut[*]}" "noinexist" )
|
||
###
|
||
f_pr titre2 "fichiers configuration divers"
|
||
f_di cmd "$confs" "grep -Ersv '^#|^$' <fichiers désirés>"
|
||
}
|
||
|
||
fi_cpu(){ # 1/12/2017
|
||
local cpu_flags text iflag var_temp qte_flags text_flags="" pluriel
|
||
local alert_microcode
|
||
|
||
cpu_flags=$( sed -n 's/^flags.*: \(.*\)$/\1/p;' /proc/cpuinfo | sed -n '1p'| \
|
||
tr ' ' '\n' | sort | tr '\n' ' ' | xargs )
|
||
[ "$CPU_FLAGS" ] || figet_cpu_flags # appel 'base' des tags, obtention $CPU_FLAGS
|
||
for iflag in $cpu_flags; do
|
||
var_temp=$( grep -E "^${iflag^^}[[:blank:]]" <<< $CPU_FLAGS )
|
||
[ "$var_temp" ] && text_flags+=" ‣ $var_temp "$'\n' || text_flags+=" ‣ $iflag\t⟷ \t? "$'\n'
|
||
done
|
||
text_flags=${text_flags% [[:cntrl:]]} # suppression espaces et \n final
|
||
[ "$cpu_flags" ] && qte_flags=$( f__wcv -w "$cpu_flags" flags )
|
||
[ "$fg_cpu" ] || figet_cpu
|
||
if ! figet_ucode ; then # retour fonction en erreur => pas d'installation mais possible
|
||
alert_microcode="$fg_ucode"
|
||
[ "$ENV_DEBIAN" ] && alert_microcode+="\n les installer: **apt install $ucode**"
|
||
fi
|
||
[ ${fg_cpu:0:1} -gt 1 ] && pluriel="s" || unset pluriel
|
||
###
|
||
f_pr titre2 "processeur"$pluriel
|
||
f_di cmd "$fg_cpu" "lscpu" # affichage proc
|
||
f_di var "$fg_uarch" "µarchitecture processeur"
|
||
f_dspl_alrt "$alert_microcode" "info"
|
||
f_pr 1 "$fg_ucode" '[[ -z "$alert_microcode" && "$fg_ucode" ]]'
|
||
f_pr
|
||
f_di var "$cpu_flags" "$qte_flags flags cpu" # flags cpu bruts
|
||
f_di sans "$text_flags" # flags cpu texte
|
||
}
|
||
|
||
fi_disk(){ # 1/12/2017
|
||
local cmd_dd_temp="" dd_temp="" exclude_df liste_df disk_df disk_df_i cmd_dfi cmd_dfh disk_lsblk fstab
|
||
local resume idResume idSwap idisk text pluriel
|
||
local alert_dd_temp alert_file_resume alert_uuidResume
|
||
[ "$fg_nb_disk" ] || figet_disk
|
||
# hddtemp
|
||
if [ $( f__which hddtemp ) ]; then
|
||
for idisk in $fg_disk_fixe; do
|
||
[ -r "/dev/$idisk" ] || continue
|
||
temp=$(( $( LC_ALL=C hddtemp -n /dev/$idisk 2>/dev/null ) ))
|
||
if [ "$temp" -ge 50 ]; then
|
||
alert_dd_temp+="$idisk: température > 50°C "$'\n'
|
||
fi
|
||
dd_temp+="$idisk: $temp °C"$'\n'
|
||
cmd_dd_temp+=" /dev/$idisk"
|
||
done
|
||
[ "$dd_temp" ] && dd_temp=${dd_temp::-1} # suppression dernier $'\n'
|
||
cmd_dd_temp="hddtemp$cmd_dd_temp"
|
||
[ "$alert_dd_temp" ] && alert_dd_temp=${alert_dd_temp::-1} # suppression dernier $'\n'
|
||
fi
|
||
# df, espaces des partitions montées seules
|
||
# exclude_df="exclude-type=aufs --exclude-type=devfs --exclude=devtmpfs --exclude-type=fdescfs
|
||
# --exclude-type=iso9660 --exclude-type=linprocfs --exclude-type=procfs --exclude-type=squashfs
|
||
# --exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs"
|
||
# disk_df=$( df -h --output=source,target,fstype,size,used,avail,pcent --$exclude_df )
|
||
# disk_df_i=$( df -i --$exclude_df )
|
||
liste_df=$( printf "/dev/%s " $fg_disk_part_fixe_m ) # $fg_disk_part_swap
|
||
disk_df="$( df -h --total --output=source,target,fstype,size,used,avail,pcent $liste_df )"
|
||
cmd_dfh="df -h --total --output=source,target,fstype,size,used,avail,pcent $liste_df"
|
||
# df -i, inoeuds
|
||
disk_df_i=$( df -i $liste_df )
|
||
cmd_dfi="df -i $liste_df"
|
||
# lsblk répertoire disques & partitions
|
||
disk_lsblk=$( lsblk -o NAME,FSTYPE,SIZE,LABEL,MOUNTPOINT,UUID )
|
||
# fstab
|
||
fstab=$( f_grep_file "/etc/fstab" "notitre" )
|
||
# resume
|
||
resume=$( f_grep_file "/etc/initramfs-tools/conf.d/resume" "notitre" )
|
||
if [ "$resume" == "nofile" ]; then
|
||
# alert resume absent
|
||
alert_file_resume="Pas de fichier _resume_ dans /etc/initramfs-tools/conf.d/ \n"
|
||
alert_file_resume+="Ce n'est pas forcément une erreur, la plus grosse partition swap devrait être "
|
||
alert_file_resume+="choisie dans ce cas. \n"
|
||
alert_file_resume+="À investiguer si erreur au boot ou boot très long ou erreur update-initramfs. \n"
|
||
alert_file_resume+="Notes: <https://kyodev.frama.io/kyopages/debian/petits-soucis/#fichier-resume> \n"
|
||
fi
|
||
idResume=$( grep -Evs '^[[:blank:]]*#|^$' /etc/initramfs-tools/conf.d/resume | sed -En 's/.*UUID=([0-9a-Z-]*).*$/\1/p' )
|
||
idSwap=$( grep -Ev '^[[:blank:]]*#|^$' /etc/fstab | sed -En 's/UUID=([0-9a-Z-]*).*swap.*$/\1/p' )
|
||
if [ "$idSwap" ] && [ "$idResume" ] && [ "$idSwap" != "$idResume" ]; then
|
||
alert_uuidResume+="vérifier la config resume, l'UUID ne correspond pas à celui du swap. \n"
|
||
alert_uuidResume+="id swap : $idSwap \nid resume: $idResume \n"
|
||
alert_uuidResume+="vous pouvez utiliser _RESUME=auto_ ou _RESUME=/dev/sdx_, voir supprimer ce fichier"
|
||
fi
|
||
[ "$fg_nb_disk" -gt 1 ] && pluriel="s" || unset pluriel
|
||
###
|
||
f_pr titre2 "disque"$pluriel
|
||
# espace des partitions fixes montées
|
||
f_pr 1 "$(gawk -F': ' '{print $1": **"$2"**"}' <<< $fg_disk_part_fix_tot)"
|
||
f_pr
|
||
f_pr l '```'
|
||
# disques fixes et amovibles
|
||
[ "$(wc -w <<< $fg_disk_fixe)" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l "$(printf '%-17s: %s' "disque$pluriel fixe$pluriel" "$fg_disk_fixe")"
|
||
[ "$(wc -w <<< $fg_disk_amov)" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l "$(printf '%-17s: %s' "disque$pluriel amovible$pluriel" "$fg_disk_amov")"
|
||
f_pr
|
||
# partitions fixes montées / swap / non montées
|
||
[ "$(wc -w <<< $fg_disk_part_fixe_m)" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l "$(printf '%-24s: %s' "partition$pluriel fixe$pluriel montée$pluriel" "$fg_disk_part_fixe_m")"
|
||
[ "$(wc -w <<< $fg_disk_part_swap)" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l "$(printf '%-24s: %s' "partition$pluriel swap$pluriel" "$fg_disk_part_swap")"
|
||
[ "$(wc -w <<< $fg_disk_part_fixe_nm)" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l "$(printf '%-28s: %s' "partition$pluriel fixe$pluriel non montée$pluriel" "$fg_disk_part_fixe_nm")"
|
||
f_pr
|
||
# partitions amovibles montées / non montées
|
||
[ "$(wc -w <<< $fg_disk_part_amov_m)" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l "$(printf '%-32s: %s' "partition$pluriel amovible$pluriel montée$pluriel" "$fg_disk_part_amov_m")"
|
||
[ "$(wc -w <<< $fg_disk_part_amov_nm)" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l "$(printf '%-32s: %s' "partition$pluriel amovible$pluriel non montée$pluriel" "$fg_disk_part_amov_nm")"
|
||
f_pr
|
||
# détails des disques par type
|
||
f_pr l "$fg_disk_table"
|
||
f_pr l '```'
|
||
f_pr
|
||
[ "$fg_nb_disk" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr 1 "**types de disque"$pluriel"** "
|
||
f_pr
|
||
f_pr l "| sata | usb | mmc | nvme |"
|
||
f_pr l "| :---: | :---: | :---: | :---: |"
|
||
f_pr l "| $fg_disk_ata | $fg_disk_usb | $fg_disk_mmc | $fg_disk_nvme |"
|
||
f_pr
|
||
# éventuellement hddtemp
|
||
f_di cmd "$dd_temp" "$cmd_dd_temp" "température disque"$pluriel
|
||
f_dspl_alrt "$alert_dd_temp" "info"
|
||
# df, espaces des partitions montées seules
|
||
f_di cmd "$disk_df" "$cmd_dfh" "utilisation disque"$pluriel
|
||
# df -i, inoeuds
|
||
f_di cmd "$disk_df_i" "$cmd_dfi" "utilisation inoeuds"
|
||
# lsblk répertoire disques & partitions
|
||
f_di cmd "$disk_lsblk" "lsblk -o NAME,FSTYPE,SIZE,LABEL,MOUNTPOINT,UUID" "disque"$pluriel" & partitions"
|
||
# fstab
|
||
f_di cmd "$fstab" "grep -Ev '^#|^$' /etc/fstab" "fstab"
|
||
# resume
|
||
f_di cmd "$resume" "grep -Evs '^#|^$' /etc/initramfs-tools/conf.d/resume" "resume"
|
||
f_dspl_alrt "$alert_file_resume" "info"
|
||
f_dspl_alrt "$alert_uuidResume" "alert"
|
||
}
|
||
|
||
fi_dmesg(){ # 2/12/2017
|
||
local dmesg_err dmesg_warn dmesg_crit file info_ucode alert_firmBug text nb_lignes=25
|
||
local alert_firmBug
|
||
|
||
file="/tmp/$$-$RANDOM-dmesg"
|
||
[ "$EUID" -eq 0 ] || echo
|
||
f__sudo "dmesg -Hk --nopager -l emerg > $file-emerg ; \
|
||
dmesg -Hk --nopager -l alert > $file-alert ; \
|
||
dmesg -Hk --nopager -l crit > $file-crit ; \
|
||
dmesg -Hk --nopager -l err > $file-err ; \
|
||
dmesg -Hk --nopager -l warn > $file-warn ; \
|
||
dmesg -Hk --nopager -l info | grep -i 'microcode: .*updated early' > $file-ucode ; \
|
||
dmesg -Hk --nopager | grep -i 'Firmware Bug' > $file-firmBug ; \
|
||
chown $fu_user: $file-*"
|
||
if [ "$?" != "0" ]; then
|
||
f__info "\n les commandes$GREEN dmesg$RED ont échoué $BLUE(droits root requis, échec authentification?)" \
|
||
"vous pouvez relancer le script complet$RED en root$BLUE pour voir les erreurs du noyau via dmesg" \
|
||
"ou juste la partie journaux avec $GREEN$DIRNAME""getInfo -j"
|
||
text+="* les commandes \`dmesg\` ont échoué, relancer avec les droits root \n\n"
|
||
echo -e "$text" >> "$fileOutput"
|
||
return 0
|
||
fi
|
||
dmesg_emerg=$( sed -n 1,"$nb_lignes"p $file-emerg )
|
||
dmesg_alert=$( sed -n 1,"$nb_lignes"p $file-alert )
|
||
dmesg_crit=$( sed -n 1,"$nb_lignes"p $file-crit )
|
||
dmesg_err=$( sed -n 1,"$nb_lignes"p $file-err )
|
||
dmesg_warn=$( sed -n 1,"$nb_lignes"p $file-warn )
|
||
[ "$dmesg_emerg" ] || dmesg_emerg=" <vide>"
|
||
[ "$dmesg_alert" ] || dmesg_alert=" <vide>"
|
||
[ "$dmesg_crit" ] || dmesg_crit=" <vide>"
|
||
[ "$dmesg_err" ] || dmesg_err=" <vide>"
|
||
[ "$dmesg_warn" ] || dmesg_warn=" <vide>"
|
||
# messages microcode
|
||
info_ucode=$( cat $file-ucode )
|
||
[ "$info_ucode" ] && info_ucode="microcode processeur mis à jour au boot"
|
||
alert_firmBug=$( cat $file-firmBug )
|
||
# suppression fichier de transfert
|
||
rm "$file-"*
|
||
###
|
||
f_pr titre2 "dmesg kernel (emergency, alerte, erreur, warning ou critique)"
|
||
f_di cmd "$dmesg_emerg" "dmesg -l emerg" "emergency, $nb_lignes premières lignes"
|
||
f_di cmd "$dmesg_alert" "dmesg -l alert" "alerte, $nb_lignes premières lignes"
|
||
f_di cmd "$dmesg_crit" "dmesg -l crit" "critique, $nb_lignes premières lignes"
|
||
f_di cmd "$dmesg_err" "dmesg -l err" "erreur, $nb_lignes premières lignes"
|
||
f_di cmd "$dmesg_warn" "dmesg -l warn" "warning, $nb_lignes premières lignes"
|
||
f_pr l "**les $nb_lignes premières lignes commencent à la date la plus ancienne encore dans les logs kernel**"
|
||
f_pr flush
|
||
f_dspl_alrt "$info_ucode" "info"
|
||
f_dspl_alrt "$alert_firmBug" "alert"
|
||
}
|
||
|
||
fi_efi(){ # 1/12/2017
|
||
local efiboot text
|
||
|
||
[ $( f__which efibootmgr ) ] || return 0 # pas d'efi
|
||
efiboot=$( gawk '
|
||
/^Boot0/ { gsub(/\\/,"\\\\",$3); printf "%s %s: \n %s \n", $1, $2, $3 };
|
||
! /^Boot0/ { print $0 }
|
||
' <<< $( efibootmgr -v 2>/dev/null ) )
|
||
###
|
||
f_pr titre2 "EFI boot manager"
|
||
f_di cmd "$efiboot" "efibootmgr -v" "config EFI boot"
|
||
}
|
||
|
||
# assigne $fg_gpu (liste des gpu), $fe_nb_gpu, fe_Xorg, si [$1=silent|xorgOnly], sortie après configs xorg complete
|
||
fi_gpu(){ # 3/12/2017
|
||
local cards cmd_cards prefixCmd openGl pluriel text
|
||
local stck_glxinfo glx_dvc cmd_glx_dvc stck_glxinfoOpt stck_glxinfoDri glx_dvc_temp
|
||
local cmd_openGl resolutions cmd_resolutions cmt_resolutions providers cmd_providers
|
||
local current_preferred cmd_current_preferred cmt_current_preferred
|
||
local modGpu cmd_modGpu cmt_modGpu srch_modGpu modVid cmd_modVid cmt_modVid srch_modVid
|
||
local alert_hybrid alert_3D alert_Wayland
|
||
local toScrut confs ifile fileConfs cmd_confs cmt_confs
|
||
# cardsManuel="$(lspci -nnk | grep -EiA 3 'vga|display|3d')" # -nn: textual and numeric ID's, k kernel
|
||
# cardsManuel="$(lspci -nnv | grep -iEA10 'vga|display|3d)" # v=verbose
|
||
# cardsManuel="lspci -nnv -s $( lspci | grep -Ei 'vga|display|3d' | cut -d" " -f1 )"
|
||
# cardsManuel="lspci -nnv -s $(gawk '/VGA |Display |3D / {print $1}' <<< $( lspci ))"
|
||
|
||
# liste/description gpu et qte
|
||
fg_gpu=$( figet_lspci "video" "name")
|
||
fe_nb_gpu=$( f__wcv "-l" "$fg_gpu" )
|
||
# version Xorg Server
|
||
fe_Xorg=$( xdpyinfoT -display $DISPLAY 2>/dev/null | grep 'version:' ) # version Xorg
|
||
fe_Xorg=${fe_Xorg//*version: /X.Org X Server}
|
||
[ "$fe_Xorg" ] || fe_Xorg=$( X -version 2>/dev/null ) # si ver Xorg vide, essai X
|
||
[ "$fe_Xorg" ] || fe_Xorg=$( Xorg -version 2>/dev/null ) # si ver Xorg vide, essai Xorg
|
||
if [ "$wayland" ]; then
|
||
xScreens=$( xrandr --verbose 2>/dev/null | grep -A1 'Screen' )
|
||
[ "$( grep 'XWAYLAND' <<< $xScreens )" ] && wayland+=" Xwayland"
|
||
[ "$( grep 'XWAYLAND' <<< $xScreens )" ] && fe_Xorg+=" {Xwayland}"
|
||
fi
|
||
|
||
[ "$1" == "silent" ] && return 0
|
||
[ "$fe_nb_gpu" -eq 0 ] && return 0 # pas de gpu, rien à voir
|
||
### ## xorgOnly
|
||
toScrut=(
|
||
'/etc/X11/xorg.conf '
|
||
'/etc/X11/xorg.conf.d/*.conf'
|
||
)
|
||
confs=$( f_grep_file "${toScrut[*]}" )
|
||
for ifile in ${toScrut[*]}; do
|
||
[ -e "$ifile" ] && fileConfs+="$ifile "
|
||
done
|
||
cmd_confs="grep -Ersv '^#|^$' $fileConfs"
|
||
[ "$fileConfs" ] || cmd_confs="Aucun fichier à afficher"
|
||
cmt_confs="configuration Xorg"
|
||
info_config="les configurations par défaut de Xorg se trouve dans **/usr/share/X11/xorg.conf.d/**, "
|
||
info_config+="non sorties ici pour cause de place."
|
||
|
||
if [ "$1" == "xorgOnly" ]; then
|
||
f_di cmd "$confs" "$cmd_confs" "$cmt_confs"
|
||
confs=$( f_grep_file "/usr/share/X11/xorg.conf.d/*" )
|
||
f_di cmd "$confs" "grep -Ersv '^#|^$' /usr/share/X11/xorg.conf.d/*" "config par défaut Xorg"
|
||
fi_log_xorg "notitre"
|
||
return 0
|
||
fi
|
||
###
|
||
# lspci
|
||
cmd_cards="lspci -nnv -s $(gawk '/VGA |Display |3D / {print $1}' <<< $( lspci ))"
|
||
if [ "$fe_nb_gpu" -eq 1 ]; then # une seule carte
|
||
cards=$( figet_lspci "video" "raw" )
|
||
else # plusieurs cartes, essai optirun ou prime
|
||
cards=$( figet_lspci "video" "raw" "graph")
|
||
prefixCmd=$(basename $(which toto) 2>/dev/null) || prefixCmd="DRI_PRIME=1"
|
||
cmd_cards="$prefixCmd $cmd_cards"
|
||
fi
|
||
if grep -iq 'Unknown header type 7f' <<< "$cards" ; then
|
||
alert_hybrid="Une carte graphique semble désactivée actuellement, lspci n'est pas complet. \n"
|
||
alert_hybrid+="Voir DRI_PRIME, vga-switcheroo, Bumbledee...?"
|
||
fi
|
||
if [[ "$wayland" && "$EUID" -eq 0 ]]; then # évite erreur $DISPLAY en root wayland
|
||
openGl="n/a:wayland root"
|
||
resolutions="n/a:wayland root"
|
||
providers="n/a:wayland root"
|
||
current_preferred="n/a:wayland root"
|
||
else
|
||
# openGl / glxinfo
|
||
if [ $( f__which glxinfo ) ]; then
|
||
stck_glxinfo=$( glxinfo )
|
||
# test 3D actif
|
||
if grep -iq 'direct rendering: No' <<< "$stck_glxinfo" ; then
|
||
alert_3D="l'accélération 3D n'est pas active"
|
||
fi
|
||
# devices
|
||
glx_dvc=$( grep -i 'direct rendering:' <<< "$stck_glxinfo" )$'\n'
|
||
glx_dvc+=$( grep 'Device: ' <<< "$stck_glxinfo" | xargs )
|
||
cmd_glx_dvc="glxinfo | grep -E 'rendering|Device: '"
|
||
if [ "$fe_nb_gpu" -gt 1 ]; then # plusieurs cartes, optirun et prime
|
||
if [ $( f__which optirun ) ]; then
|
||
stck_glxinfoOpt=$( optirun glxinfo )
|
||
glx_dvc_temp=$( grep 'Device: ' <<< $stck_glxinfoOpt | xargs )
|
||
cmd_glx_dvc="optirun $cmd_glx_dvc"
|
||
else
|
||
stck_glxinfoDri=$( DRI_PRIME=1 glxinfo )
|
||
glx_dvc_temp=$( grep 'Device: ' <<< $stck_glxinfoDri | xargs )
|
||
cmd_glx_dvc="DRI_PRIME=1 $cmd_glx_dvc"
|
||
fi
|
||
[ "$glx_dvc_temp" != "$glx_dvc" ] && glx_dvc+="\n$glx_dvc_temp" # ajout si diff
|
||
fi
|
||
# openGL
|
||
fi_gpu_openGl # openGl pour une carte ou gpu de base
|
||
if [ "$fe_nb_gpu" -gt 1 ]; then # plusieurs cartes, optirun et prime
|
||
if [ $( f__which optirun ) ]; then
|
||
fi_gpu_openGl "opt" # ajout à $openGl existant, pas de redondance
|
||
cmd_openGl="optirun glxinfo"
|
||
else # DRI
|
||
fi_gpu_openGl "dri" # redondance
|
||
cmd_openGl="DRI_PRIME=1 glxinfo"
|
||
fi
|
||
else
|
||
cmd_openGl="glxinfo | grep -E "
|
||
cmd_openGl+="'OpenGL vendor|OpenGL renderer|OpenGL version|shading language|OpenGL extensions'"
|
||
fi
|
||
openGl=${openGl// string:/:} # suppression chaîne ' string'
|
||
openGl=${openGl% } # suppression espace final éventuel
|
||
fi
|
||
# xrandr: résolutionS & providers & preferred/current
|
||
if [ $( f__which xrandr ) ]; then
|
||
resolutions="$( xrandr --query | grep -A11 'Screen [0-9]' )"
|
||
cmd_resolutions="xrandr --query | grep -A11 'Screen [0-9]'"
|
||
cmt_resolutions="10 premières résolutions possibles"
|
||
providers="$( xrandr --listproviders )" # DRI: ok, sort 2 fournisseurs
|
||
cmd_providers="xrandr --listproviders"
|
||
current_preferred="$( xrandr --verbose | grep -EA2 'current|preferred' )"
|
||
cmd_current_preferred="xrandr --verbose | grep -EA2 'current|preferred'"
|
||
cmt_current_preferred="résolution courante et préférée"
|
||
fi
|
||
fi
|
||
# modules
|
||
figet_modules "gpu"
|
||
modGpu="$fg_modules" # modules chargés
|
||
cmd_modGpu="lsmod | grep -Ew '$fg_modKernel'" # module driver
|
||
[ "$( f__wcv -l "$modGpu" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_modGpu="**Gpu:** $( f__wcv -l "$modGpu" ) module"$pluriel" utilisé"$pluriel" *"
|
||
srch_modGpu=${fg_modMotif//|/ } # fg_modMotif motif de recherche, avec |
|
||
figet_modules "video"
|
||
modVid="$fg_modules" # modules chargés
|
||
cmd_modVid="lsmod | grep -Ew '$fg_modKernel'" # module driver
|
||
[ "$( f__wcv -l "$modVid" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_modVid="**Video:** $( f__wcv -l "$modVid" ) module"$pluriel" utilisé"$pluriel" *"
|
||
srch_modVid=${fg_modMotif//|/ } # fg_modMotif motif de recherche, avec |
|
||
# fonctions externes
|
||
[ "$fg_resolution" ] || figet_screen
|
||
###
|
||
f_pr titre2 "graphisme"
|
||
f_pr l "$( sed -E 's/(.*)/**\1** /' <<< $fg_gpu )" # mise en gras
|
||
f_pr
|
||
# nb écran & résolution(s) active(s)
|
||
f_pr l "nombre d'écrans: **$fg_nb_screen**"
|
||
[ $( f__wcv "-wv" "$fg_resolution" "pixels" ) -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l "résolution"$pluriel" active"$pluriel": **$fg_resolution**"
|
||
f_pr
|
||
# lspci -nnv
|
||
f_di cmd "$cards" "$cmd_cards"
|
||
f_dspl_alrt "$alert_hybrid" "alert"
|
||
# wayland
|
||
f_dspl_alrt "$alert_Wayland" "info"
|
||
# openGl
|
||
f_di cmd "$glx_dvc" "$cmd_glx_dvc" "devices OpenGl"
|
||
f_dspl_alrt "$alert_3D" "info"
|
||
f_di cmd "$openGl" "$cmd_openGl" "OpenGl"
|
||
# liste providers, preferred & current
|
||
f_di cmd "$current_preferred" "$cmd_current_preferred" "$cmt_current_preferred"
|
||
f_di cmd "$providers" "$cmd_providers"
|
||
# résolutions possibles, pas d'affichage si mode (ssh) ou xrandr pas accessible
|
||
f_di cmd "$resolutions" "$cmd_resolutions" "$cmt_resolutions"
|
||
# modules vidéo
|
||
f_di cmd "$modGpu" "$cmd_modGpu" "$cmt_modGpu"
|
||
f_di var "$srch_modGpu" "" "* recherche parmi:"
|
||
f_di cmd "$modVid" "$cmd_modVid" "$cmt_modVid"
|
||
f_di var "$srch_modVid" "" "* recherche parmi:"
|
||
# Xorg config
|
||
f_di cmd "$confs" "$cmd_confs" "$cmt_confs"
|
||
f_dspl_alrt "$info_config" "info"
|
||
}
|
||
|
||
# $1="[opt|dri]", assigne $openGl, sous fonction de fi_gpu
|
||
fi_gpu_openGl(){ # 28/11/2017
|
||
local iogl dri_glxinfo=""
|
||
|
||
[[ "$1" == "opt" ]] && openGl+="\n---- \n"
|
||
toScrut=(
|
||
'OpenGL vendor'
|
||
'OpenGL renderer'
|
||
'OpenGL version'
|
||
'shading language'
|
||
'OpenGL extensions'
|
||
)
|
||
for iogl in "${toScrut[@]}" ; do
|
||
if [ "$1" == "dri" ]; then
|
||
dri_glxinfo+=$( grep "$iogl" <<< $stck_glxinfoDri )$'\n'
|
||
elif [ "$1" == "opt" ]; then
|
||
openGl+=$( grep "$iogl" <<< $stck_glxinfoOpt )$'\n'
|
||
else
|
||
openGl+=$( grep "$iogl" <<< "$stck_glxinfo" )$'\n'
|
||
fi
|
||
done
|
||
if [ "$1" == "dri" ]; then
|
||
dri_glxinfo=${dri_glxinfo::-1}
|
||
[ $( f__which uniq ) ] && openGl=$( uniq <<< $dri_glxinfo ) || openGl="$dri_glxinfo"
|
||
fi
|
||
openGl=${openGl::-1}
|
||
}
|
||
|
||
fi_hw(){ # 1/12/2017
|
||
[ "$fg_hw" ] || figet_hw
|
||
###
|
||
f_pr titre2 "hardware monitor acpi"
|
||
f_di sans "$fg_hw" "sans"
|
||
f_pr 1 "pas d'informations détectées" '[ -z "$fg_hw" ]'
|
||
f_pr flush
|
||
}
|
||
|
||
fi_journal(){ # 2/12/2017
|
||
local jctl_boot jctl_alert_k jctl_crit_k jctl_err_k jctl_warn_k jctl_warn_nok jctl_last jctl_size file
|
||
local info_ucode text nb_lignes=25
|
||
local alert_jctl_persist alert_firmBug
|
||
|
||
if [ -z $( f__which journalctl ) ]; then
|
||
fi_dmesg # pas systemd, appel dmesg
|
||
return 0
|
||
fi
|
||
|
||
file="/tmp/$$-$RANDOM-journalctl"
|
||
[ "$EUID" -eq 0 ] || echo
|
||
f__sudo " LC_ALL=C journalctl --no-hostname --boot -1 &>$file-persistant ; \
|
||
LC_ALL=C journalctl --no-pager --no-hostname -b0 -k -p 1 > $file-alert ; \
|
||
LC_ALL=C journalctl --no-pager --no-hostname -b0 -k -p 2..2 > $file-crit ; \
|
||
LC_ALL=C journalctl --no-pager --no-hostname -b0 -p 3..3 > $file-err ; \
|
||
LC_ALL=C journalctl --no-pager --no-hostname -b0 -p 4..4 > $file-warn ; \
|
||
LC_ALL=C journalctl --no-pager --no-hostname -b0 -p 4 -n$nb_lignes > $file-last ; \
|
||
LC_ALL=C journalctl --disk-usage > $file-size ; \
|
||
LC_ALL=C journalctl --no-pager --no-hostname -o short-monotonic --boot 0 -k -p6 | grep -i 'microcode: .*updated early' > $file-ucode ; \
|
||
[ $( type -p dmesg 2>/dev/null ) ] && dmesg -Hk --nopager | grep -i 'Firmware Bug' > $file-firmBug ; \
|
||
chown $fu_user: $file-*"
|
||
if [ "$?" != "0" ]; then
|
||
f__info "\n les commandes$GREEN journalctl$RED ont échoué $BLUE(droits root requis, échec authentification?)" \
|
||
"vous pouvez relancer le script complet$RED en root$BLUE pour voir les erreurs des journaux" \
|
||
"ou juste la partie journaux avec $GREEN$DIRNAME""getInfo -j"
|
||
text+="* les commandes \`journalctl\` ont échoué, relancer avec les droits root \n\n"
|
||
echo -e "$text" >> "$fileOutput"
|
||
return 0
|
||
fi
|
||
# début des logs, extraction à partir de file-last (toujours lignes) pour début des logs
|
||
jctl_boot=$( gawk -F '--|,' 'FNR==1 {print $2}' $file-last )
|
||
jctl_boot=$( date -d "${jctl_boot##*begin at }" ) # passage en date locale
|
||
# test persistance
|
||
if grep -iq 'no persistent journal' "$file-persistant"; then
|
||
alert_jctl_persist="les journaux ne sont pas persistants, revoir les logs du précédent boot "
|
||
alert_jctl_persist+="n'est donc pas possible pour investigation avec: \n"
|
||
alert_jctl_persist+="$spc5 **journalctl --no-hostname --boot -1**"
|
||
fi
|
||
# journaux kernel
|
||
jctl_alert_k=$( sed '/kernel:/!d' $file-alert | sed -n 1,"$nb_lignes"p ) # emergency & alert
|
||
jctl_crit_k=$( sed '/kernel:/!d' $file-crit | sed -n 1,"$nb_lignes"p )
|
||
jctl_err_k=$( sed '/kernel:/!d' $file-err | sed -n 1,"$nb_lignes"p ) # uniquement lignes avec kernel, élimine no entries et logs begin
|
||
jctl_warn_k=$( sed '/kernel:/!d' $file-warn | sed -n 1,"$nb_lignes"p )
|
||
# taille des journaux
|
||
jctl_size=$( grep -Eo '[0-9]*\.[0-9]*[[:alpha:]]{1,2}' $file-size | sed 's/M/ Mo/' )
|
||
# signalement fichier vides ou suppression origine kernel (gain de place)
|
||
[ "$jctl_alert_k" ] && jctl_alert_k=${jctl_alert_k//kernel:/:} || jctl_alert_k=" ‣ vide"
|
||
[ "$jctl_crit_k" ] && jctl_crit_k=${jctl_crit_k//kernel:/:} || jctl_crit_k=" ‣ vide"
|
||
[ "$jctl_err_k" ] && jctl_err_k=${jctl_err_k//kernel:/:} || jctl_err_k=" ‣ vide"
|
||
[ "$jctl_warn_k" ] && jctl_warn_k=${jctl_warn_k//kernel:/:} || jctl_warn_k=" ‣ vide"
|
||
# journaux hors kernel
|
||
jctl_alert_nok=$( sed '/-- Logs begin/d;/kernel:/d; s/-- No entries --/ ‣ vide/' $file-alert | \
|
||
sed -n 1,"$nb_lignes"p )
|
||
jctl_crit_nok=$( sed '/-- Logs begin/d;/kernel:/d; s/-- No entries --/ ‣ vide/' $file-crit | \
|
||
sed -n 1,"$nb_lignes"p )
|
||
jctl_err_nok=$( sed '/-- Logs begin/d;/kernel:/d; s/-- No entries --/ ‣ vide/' $file-err | \
|
||
sed -n 1,"$nb_lignes"p )
|
||
jctl_warn_nok=$( sed '/-- Logs begin/d;/kernel:/d; s/-- No entries --/ ‣ vide/;s/<warn>//
|
||
' $file-warn | sed -n 1,"$nb_lignes"p )
|
||
# dernières lignes, toute provenance
|
||
jctl_last=$( sed '/-- Logs begin/d; s/-- No entries --/ ‣ vide/;s/<warn>//' $file-last )
|
||
# messages microcode
|
||
info_ucode=$( cat $file-ucode )
|
||
[ "$info_ucode" ] && info_ucode="microcode processeur mis à jour au boot"
|
||
alert_firmBug=$( grep -i 'Firmware Bug' <<< $jctl_err_k )$'\n'
|
||
alert_firmBug=${alert_firmBug%%[[:space:]]}
|
||
alert_firmBug+=$( cat $file-firmBug 2>/dev/null )
|
||
alert_firmBug=${alert_firmBug%%[[:space:]]}
|
||
# suppression fichier de transfert
|
||
rm "$file-"*
|
||
###
|
||
f_pr titre2 "journalctl kernel (emergency, alert, erreur, warning ou critique)"
|
||
f_pr 1 "**journaux persistants**" '[ -z "$alert_jctl_persist" ]'
|
||
f_pr 1 "Début des log: **$jctl_boot**"
|
||
f_pr
|
||
f_dspl_alrt "$alert_jctl_persist" "info"
|
||
# journaux kernel
|
||
f_di cmd "$jctl_alert_k" "journalctl --no-hostname -b0 -k -p1" \
|
||
"**kernel emergency 0 & alerte 1**, $nb_lignes premières lignes"
|
||
f_di cmd "$jctl_crit_k" "journalctl --no-hostname -b 0 -k -p 2..2" \
|
||
"**kernel critique**, $nb_lignes premières lignes"
|
||
f_di cmd "$jctl_err_k" "journalctl --no-hostname -b0 -k -p 3..3" \
|
||
"**kernel erreur**, $nb_lignes premières lignes)"
|
||
f_di cmd "$jctl_warn_k" "journalctl --no-hostname -b0 -k -p 4..4" \
|
||
"**kernel warning**, $nb_lignes premières lignes"
|
||
# journaux hors kernel
|
||
f_pr titre2 "journalctl hors kernel (emergency, alert, erreur, warning ou critique)"
|
||
f_pr 1 "Début des log: **$jctl_boot**"
|
||
f_pr
|
||
f_di cmd "$jctl_alert_nok" "journalctl --no-hostname -b0 -p 1 | grep -v kernel" \
|
||
"**hors kernel, emergency 0 & alerte 1**, $nb_lignes premières lignes"
|
||
f_di cmd "$jctl_crit_nok" "journalctl --no-hostname -b0 -p 2..2 | grep -v kernel" \
|
||
"**hors kernel, critique**, $nb_lignes premières lignes"
|
||
f_di cmd "$jctl_err_nok" "journalctl --no-hostname -b0 -p 3..3 | grep -v kernel" \
|
||
"**hors kernel, erreur**, $nb_lignes premières lignes"
|
||
f_di cmd "$jctl_warn_nok" "journalctl --no-hostname -b0 -p 4..4 | grep -v kernel" \
|
||
"**hors kernel, warning**, $nb_lignes premières lignes"
|
||
#informations
|
||
f_pr 1 "les $nb_lignes premières lignes commencent à la date du dernier boot"
|
||
f_pr
|
||
f_di cmd "$jctl_size" "journalctl --disk-usage " "taille des journaux"
|
||
# dernières lignes
|
||
f_di cmd "$jctl_last" "journalctl --no-pager --no-hostname -b0 -p 4 -n25" \
|
||
"**toutes provenance, emergency-warning**, $nb_lignes lignes les plus **récentes**"
|
||
f_dspl_alrt "$alert_firmBug" "alert"
|
||
f_dspl_alrt "$info_ucode" "info"
|
||
}
|
||
|
||
fi_locale(){ # 1/12/2017
|
||
local locale localectl timezone timedatectl xKeyboardMap keyboard text
|
||
local alert_rtc alert_ntp
|
||
|
||
# locale
|
||
locale="$(f_grep_file "/etc/default/locale* /etc/locale.conf")"
|
||
[ $( f__which localectl ) ] && localectl=$( localectl --no-pager status )
|
||
# timezone
|
||
timezone="$(f_grep_file "/etc/timezone*")"
|
||
if [ $( f__which timedatectl ) ]; then
|
||
timedatectl=$( LC_ALL=C timedatectl status --no-pager )
|
||
if grep -iq 'Network time on: no' <<< "$timedatectl"; then
|
||
alert_ntp="Network time on: no \n"
|
||
alert_ntp+="Le système ne synchronise pas l'heure sur un serveur NTP. Si ce n'est pas voulu: \n"
|
||
alert_ntp+="activer le service: timedatectl set-ntp true \n"
|
||
alert_ntp+="et/ou installer le démon Ntp: apt install ntp"
|
||
fi
|
||
if grep -iq 'RTC in local TZ: yes' <<< "$timedatectl"; then
|
||
alert_rtc="RTC in local TZ: yes \n"
|
||
alert_rtc+="L’horloge système doit être en UTC pour que les applications de date et "
|
||
alert_rtc+="heure fonctionnent correctement avec le fuseau horaire configuré sur le système. \n"
|
||
alert_rtc+="Les modifications d’heure d’été/hiver peuvent être incohérentes quand l’horloge "
|
||
alert_rtc+="matérielle est en heure locale."
|
||
fi
|
||
fi
|
||
# keyboard layout
|
||
keyboard=$( f_grep_file "/etc/default/keyboard*" )
|
||
if [[ "$wayland" && "$EUID" -eq 0 ]]; then # évite erreur $DISPLAY en root wayland
|
||
xKeyboardMap="n/a en root sous wayland"
|
||
else
|
||
[ $( f__which setxkbmap ) ] && xKeyboardMap="$(setxkbmap -query)"
|
||
fi
|
||
###
|
||
f_pr titre2 "localisation"
|
||
# locale
|
||
f_di cmd "$locale" "grep -Esv '#|^$' /etc/default/locale* /etc/locale.conf"
|
||
f_di cmd "$localectl" "localectl --no-pager status"
|
||
# timezone
|
||
f_di cmd "$timezone" "grep -EHsv '#|^$' /etc/timezone*"
|
||
f_di cmd "$timedatectl" "timedatectl status --no-pager"
|
||
f_dspl_alrt "$alert_ntp" "info"
|
||
f_dspl_alrt "$alert_rtc" "alert"
|
||
# keyboard layout
|
||
f_di cmd "$keyboard" "grep -EHv '#|^$' /etc/default/keyboard*"
|
||
f_di cmd "$xKeyboardMap" "setxkbmap -query"
|
||
}
|
||
|
||
# [$1=notitre]
|
||
fi_log_xorg(){ # 3/12/2017
|
||
local toScrut xfile xfileTest="" logXorg cmd_logXorg="" cmt_logXorg extract dateFile text nb_lignes=50
|
||
local info_logs
|
||
|
||
[[ "$ENV_SSH" || "$ENV_DISPLAY" ]] && return 0
|
||
toScrut=(
|
||
/var/log/Xorg.0.log
|
||
/home/$fu_user/.local/share/xorg/Xorg.0.log
|
||
/var/lib/gdm3/.local/share/xorg/Xorg.0.log
|
||
)
|
||
# checkpoint
|
||
for xfile in ${toScrut[@]}; do
|
||
[ -e "$xfile" ] && xfileTest+="y"
|
||
done
|
||
[ ${#xfileTest} -eq 0 ] && return 0 # aucun fichier à tester (wayland?), retour
|
||
|
||
# coeur fonction
|
||
for xfile in ${toScrut[@]}; do
|
||
if [ -e "$xfile" ]; then
|
||
dateFile=$( date -r $xfile '+%d/%m/%Y %H:%M %z' )
|
||
extract=$( grep -Es '\(WW\)|\(EE\)|\(\?\?\)' $xfile | sed '/(WW) warning, (EE) error,/d' )
|
||
extract="$(sed -n 1,"$nb_lignes"p <<< $extract)"
|
||
if [ "$extract" ]; then
|
||
logXorg+=" $xfile, date de modification: $dateFile \n\n"
|
||
logXorg+=" (WW) **warning**, (EE) **erreur**, (??) inconnu, $nb_lignes premières lignes \n"
|
||
logXorg+="$(grep -E '\(EE\)' <<< $extract) \n"
|
||
logXorg+="$(grep -E '\(WW\)' <<< $extract) \n"
|
||
logXorg+="$(grep -E '\(\?\?\)' <<< $extract) "$'\n\n'
|
||
cmd_logXorg+="$xfile "
|
||
else
|
||
logXorg+=" $xfile : <vide> "$'\n\n'
|
||
fi
|
||
else
|
||
logXorg+=" $xfile : <inexistant> "$'\n\n'
|
||
fi
|
||
done
|
||
logXorg=${logXorg::-2}
|
||
[ "$cmd_logXorg" ] && cmd_logXorg=${cmd_logXorg% } || cmd_logXorg="<emplacement>"
|
||
info_logs="voir les options appliquées par défaut: **cat $cmd_logXorg | grep '(\\\*\\\*)**' "
|
||
cmd_logXorg="grep -Es '\(WW\)|\(EE\)|\(\?\?\)' $cmd_logXorg"
|
||
cmt_logXorg="Xorg.log"
|
||
###
|
||
f_pr titre2 "journaux Xorg" "[ \"$1\" != \"notitre\" ]"
|
||
f_di cmd "$logXorg" "$cmd_logXorg" "$cmt_logXorg"
|
||
f_dspl_alrt "$info_logs" "info"
|
||
}
|
||
|
||
fi_mem(){ # 1/12/2017
|
||
local memoire swappiness text
|
||
|
||
figet_mem "mem" #options possibles mem swap total notitle nocoltitle
|
||
memoire="$fg_mem \n"
|
||
figet_mem "swap" "notitle"
|
||
memoire+="$fg_mem"
|
||
swappiness=$( cat /proc/sys/vm/swappiness 2>/dev/null )
|
||
###
|
||
f_pr titre2 "mémoire"
|
||
f_di cmd "$memoire" "cmd" "free -h"
|
||
f_di cmd "$swappiness" "cmd" "cat /proc/sys/vm/swappiness"
|
||
}
|
||
|
||
# [$1=silent], assigne fe_nb_reseau, fe_cards_reseau
|
||
fi_net(){ # 1/12/2017 ( matériel )
|
||
local cards cmd_cards modEth cmd_modEth cmt_modEth srch_modEth pluriel text
|
||
local modWln cmd_modWln cmt_modWln srch_modWln
|
||
local alert_wlx
|
||
|
||
# devices
|
||
fe_cards_reseau=$( figet_lspci "net" "name" )
|
||
fe_nb_reseau=$(f__wcv -l "$fe_cards_reseau")
|
||
[ "$1" == "silent" ] && return
|
||
[ "$fe_nb_reseau" -eq 0 ] && return 0 # pas de cartes réseau, rien à voir (en attendant usb ou autre)
|
||
###
|
||
# lspci
|
||
cards=$( figet_lspci "net" "raw" )
|
||
cmd_cards="lspci -nnv | grep -EiA 15 'network|ethernet'"
|
||
# cardsManuel="$(lspci -nnk | grep -EiA 5 'network|ethernet')"
|
||
# cardsManuel="$(lspci -nnv | grep -EiA 15 'network|ethernet')"
|
||
# cardsManuel="lspci -nnv -s $( lspci | grep -Ei 'network|ethernet' | cut -d" " -f1 )" si devices plusieurs slots???
|
||
#modules
|
||
figet_modules "ethernet"
|
||
modEth="$fg_modules" # modules chargés
|
||
cmd_modEth="lsmod | grep -Ew '$fg_modKernel'" # module driver
|
||
[ "$( f__wcv -l "$modEth" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_modEth="**Ethernet:** $( f__wcv -l "$modEth" -gt 1 ) module"$pluriel" utilisé"$pluriel" *"
|
||
srch_modEth=${fg_modMotif//|/ } # fg_modMotif motif de recherche, avec |
|
||
figet_modules "wireless"
|
||
|
||
modWln="$fg_modules" # modules chargés
|
||
cmd_modWln="lsmod | grep -Ew '$fg_modKernel'" # module driver
|
||
[ "$( f__wcv -l "$modWln" )" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_modWln="**Wifi:** $( f__wcv -l "$modWln" -gt 1 ) module"$pluriel" utilisé"$pluriel" *"
|
||
srch_modWln=${fg_modMotif//|/ } # fg_modMotif motif de recherche, avec |
|
||
[ "$fg_ip" ] || figet_ip
|
||
if grep -iq 'wlx' <<< "$fg_ifn"; then
|
||
alert_wlx="Une interface wifi est en erreur: $(grep -o 'wlx' <<< $fg_ifn) \n"
|
||
alert_wlx+="l'interface n'est pas reconnue et est donc mal nommée, "
|
||
alert_wlx+="éventuellement, changer le renommage: \n"
|
||
alert_wlx+="https://kyodev.frama.io/kyopages/trucs/interfaces-nommage-classique/"
|
||
fi
|
||
###
|
||
f_pr titre2 "réseau"
|
||
f_pr l "$(sed -E 's/(.*)/**\1**/' <<< $fe_cards_reseau)" '' # mise en gras
|
||
f_pr
|
||
# lspci -nnv
|
||
f_di cmd "$cards" "$cmd_cards"
|
||
# modules réseau
|
||
f_di cmd "$modWln" "$cmd_modWln" "$cmt_modWln"
|
||
f_di var "$srch_modWln" "" "* recherche parmi:"
|
||
f_di cmd "$modEth" "$cmd_modEth" "$cmt_modEth"
|
||
f_di var "$srch_modEth" "" "* recherche parmi:"
|
||
f_dspl_alrt "$alert_wlx" "alert"
|
||
}
|
||
|
||
fi_nm(){ # 1/12/2017
|
||
[ $( f__which nmcli ) ] || return 0
|
||
local nm_etat cmd_nm_etat cmt_nm_etat nm_conf cmd_nm_conf cmt_nm_conf nm_wifis cmd_nm_wifis cmt_nm_wifis
|
||
local nm_connected text
|
||
|
||
nm_etat=$( f_grep_file "/var/lib/NetworkManager/NetworkManager.state" "notitre" )
|
||
cmd_nm_etat="grep -Ev '#|^$' /var/lib/NetworkManager/NetworkManager.state"
|
||
cmt_nm_etat="état de NetworkManager"
|
||
nm_conf=$( f_grep_file "/etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/conf.d/*.conf" )
|
||
cmd_nm_conf="grep -Ev '#|^$' /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/conf.d/*.conf"
|
||
cmt_nm_conf="configuration de NetworkManager"
|
||
nm_wifis=$( LC_ALL=C nmcli -f SSID,BSSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY device wifi list | head -n15 )
|
||
cmd_nm_wifis="nmcli -f SSID,BSSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY device wifi list"
|
||
cmt_nm_wifis="wifis à proximité"
|
||
[ "$(f__wcv "-l" "$nm_wifis")" -eq 1 ] && unset nm_wifis
|
||
nm_connected=$( LC_ALL=C nmcli -f SSID,ACTIVE,IN-USE device wifi list | gawk '/yes[[:space:]]+\*/ {print $1}' )
|
||
###
|
||
f_pr titre2 "NetworkManager"
|
||
f_di cmd "$nm_etat" "cmd" "$cmd_nm_etat" "$cmt_nm_etat"
|
||
f_di cmd "$nm_conf" "cmd" "$cmd_nm_conf" "$cmt_nm_conf"
|
||
f_di cmd "$nm_wifis" "cmd" "$cmd_nm_wifis" "$cmt_nm_wifis"
|
||
}
|
||
|
||
fi_packagers(){ #v2 23/11/2017
|
||
local alert_pkg_todo="ce gestionnaire de paquets n'est pas maîtrisé par manque d'expertise \n"
|
||
alert_pkg_todo+="vous êtes donc bienvenus à contribuer dans ce domaine: \n"
|
||
alert_pkg_todo+="https://framagit.org/kyodev/kyopages/blob/master/scripts/CONTRIB.md#getinfo"
|
||
|
||
if type -p dpkg &>/dev/null ; then # debian, buntu apt/dpkg
|
||
unset alert_pkg_todo # modèle, alert_pkg_todo pas implanté dans fi_pkg_apt
|
||
fi_pkg_apt "apt:apt/dpkg"
|
||
elif type -p dnf &>/dev/null || type -p yum &>/dev/null ; then # Fedora, RedHat (rpm)
|
||
fi_pkg_x "dnf:dnf/rpm"
|
||
elif type -p pacman &>/dev/null ; then # ArchLinux, Chakra Linux, Manjaro, KaOS, Parbola, Antergos, Apricity
|
||
fi_pkg_x "pacman:Pacman"
|
||
elif type -p pacman-g2 &>/dev/null ; then # Frugalware
|
||
fi_pkg_x "pacman-g2:Pacman-g2"
|
||
elif type -p emerge &>/dev/null ; then # Gentoo
|
||
fi_pkg_x "portage:portage/emerge"
|
||
elif type -p installpkg &>/dev/null || type -p slackpkg &>/dev/null ; then # Slackware, slackpkg gestion automatique paquets
|
||
fi_pkg_x "slackware:Slackware"
|
||
elif type -p zypper &>/dev/null ; then # Suse, openSuse
|
||
fi_pkg_x "zypper:zypper/rpm"
|
||
elif type -p alps &>/dev/null ; then # AryaLinux
|
||
fi_pkg_x "x:alps"
|
||
elif type -p eopkg &>/dev/null ; then # Solus Linux
|
||
fi_pkg_x "x:eopkg"
|
||
elif type -p guix &>/dev/null ; then # GNU Guix
|
||
fi_pkg_x "x:Guix"
|
||
elif type -p lvu &>/dev/null ; then # Lunar Linux
|
||
fi_pkg_x "x:lvu"
|
||
elif type -p nix-env &>/dev/null ; then # Nix: NixOs
|
||
fi_pkg_x "x:Nix"
|
||
elif type -p opkg &>/dev/null ; then # opkg fork ipkg, ipkg (abandonné) sauf sur Syno?
|
||
fi_pkg_x "x:opkg"
|
||
elif type -p sorcery &>/dev/null ; then # SourceMage
|
||
fi_pkg_x "x:Sorcery"
|
||
elif type -p tazpkg &>/dev/null ; then # SliTaz
|
||
fi_pkg_x "x:tazpkg"
|
||
elif type -p tce-status &>/dev/null ; then # TinyCoreLinux
|
||
fi_pkg_x "x:TinyCoreExtensions"
|
||
elif type -p xbps-query &>/dev/null ; then # VoidLinux
|
||
fi_pkg_x "x:VoidLinux"
|
||
else
|
||
fi_pkg_x "x:Inconnue"
|
||
fi
|
||
}
|
||
|
||
fi_pkg_apt(){ #v3 5/12/2017
|
||
local dateMaj nb_packages ifile info_update text pluriel
|
||
local sources cmt_sources cmd_sources
|
||
local apt_v apt_version apt_prefs cmt_apt_prefs cmd_apt_prefs
|
||
local stck_upgd qte_upgradable
|
||
local upgrade cmt_upgrade cmd_upgrade
|
||
local notUpgraded cmt_notUpgraded
|
||
local toRemove qte_toRemove cmt_toRemove cmd_toRemove
|
||
local autoclean qte_autoclean cmt_autoclean cmd_autoclean size_clean size_cleanH
|
||
local clean qte_clean cmt_clean cmd_clean size_clean
|
||
local non_ii qte_non_ii cmt_non_ii cmd_non_ii etat ligne stck_etat
|
||
local deborphan qte_deborphan cmt_deborphan cmd_deborphan
|
||
local holded qte_holded cmt_holded cmd_holded
|
||
local alert_https alert_httpsPossible alert_non_list alert_httpredir alert_upgrade alert_full_upgrade
|
||
local alert_apt alert_remove alert_autoclean alert_clean alert_non_ii alert_deborphan
|
||
|
||
# sources
|
||
sources=$( f_grep_file "/etc/apt/sources.list /etc/apt/sources.list.d/*.list" 8 )
|
||
cmt_sources="dépôts"
|
||
cmd_sources="grep -Ersv '^#|^$' /etc/apt/sources.list /etc/apt/sources.list.d/*.list"
|
||
if [ $( ls -1 /etc/apt/sources.list.d/ | grep -cEv '\.list$' ) -gt 0 ]; then
|
||
for ifile in $( ls /etc/apt/sources.list.d/* ); do
|
||
if [[ ${ifile##*.} != "list" ]]; then
|
||
alert_non_list+="$ifile: ignoré, extension non valable"
|
||
fi
|
||
done
|
||
fi
|
||
# apt prefs
|
||
apt_prefs=$( f_grep_file "/etc/apt/preferences.d/*" )
|
||
cmd_apt_prefs="grep -Erv '^#|^$' /etc/apt/preferences.d/"
|
||
cmt_apt_prefs="préférences apt"
|
||
if [ "$1" == "confOnly" ]; then
|
||
local apt_unUpgrd cmd_unUpgrd cmd_apt_history essai
|
||
shopt -s extglob
|
||
# apt_unUpgrd=$( f_grep_file "/etc/apt/apt.conf.d/!(*.save)" "comment//" )
|
||
apt_unUpgrd=$( f_grep_file "/etc/apt/apt.conf.d/50unattended-upgrades" "comment//" )
|
||
cmd_unUpgrd="grep -Erv '^//|^$' /etc/apt/apt.conf.d/50unattended-upgrades"
|
||
[ "$apt_unUpgrd" ] && info_unUpgrd="les logs spécifiques unattended-upgrades: "
|
||
info_unUpgrd+="**ls -l /var/log/unattended-upgrades/*.log**"
|
||
f_di cmd "$sources" "$cmd_sources" "$cmt_sources"
|
||
f_di cmd "$apt_prefs" "$cmd_apt_prefs" "$cmt_apt_prefs"
|
||
f_di cmd "$apt_unUpgrd" "$cmd_unUpgrd" ".conf unattended-upgrades"
|
||
f_dspl_alrt "$info_unUpgrd" "info"
|
||
#f_di cmd "$( cat /var/log/syslog | tail -n20 )" "cat /var/log/syslog | tail -n20" "20 derniers logs"
|
||
#f_di cmd "$( cat /var/log/apt/history.log | tail -n25 )" "cat /var/log/apt/history.log | tail -n25" "25 derniers historiques apt"
|
||
#f_di sans "$( f_grep_file "/var/log/unattended-upgrades/*.log" )"
|
||
IFS=$'\n'
|
||
essai=($(cat /var/log/apt/history.log | grep -B1 -A2 'unattended-upgrade'))
|
||
# for i in "${!essai[@]}"; do
|
||
# for i in /var/log/unattended-upgrades/* ; do
|
||
# done
|
||
# f_di cmd $(echo "${essai[*]}") "$cmt_apt_history"
|
||
#echo ${#essai[*]}
|
||
#echo ${essai[3]}
|
||
IFS="$IFS_INI"
|
||
return 0
|
||
fi
|
||
# avertissement
|
||
info_update="apt update n'a pas été lancé. vérifier que la date de mise à jour ne soit "
|
||
info_update+="pas trop ancienne, la précision de cette partie du rapport pourra en être améliorée."
|
||
# divers
|
||
dateMaj=$( date -r /var/cache/apt/pkgcache.bin '+%d/%m/%Y %H:%M %z' 2>/dev/null) || \
|
||
dateMaj=$( date -r /var/cache/apt '+%d/%m/%Y %H:%M %z' 2>/dev/null ) # /var/lib/dpkg/
|
||
nb_packages=$( dpkg -l | grep -c '^ii' )
|
||
# https
|
||
apt_version=$( apt --version ) # apt 1.4.8 (i386)
|
||
apt_version=${apt_version#apt } # 1.4.8 (i386)
|
||
apt_version=${apt_version% (*} # 1.4.8
|
||
apt_v=${apt_version%.*} # 1.4
|
||
alert_https=$( gawk '{if ( $1 > 1.5 ) {print "https inutile"}}' <<< $apt_v )
|
||
if f__requis "apt-transport-https" "debOnly" && [ "$alert_https" ]; then
|
||
alert_https="le paquet <apt-transport-https> est inutile maintenant avec la version $apt_v d'apt (depuis 1.6)"
|
||
else
|
||
unset alert_https
|
||
fi
|
||
alert_httpsPossible=$( gawk '{if ( $1 > 1.5 ) {print "https possible"}}' <<< $apt_v )
|
||
if [ "$alert_httpsPossible" ]; then
|
||
alert_httpsPossible="votre version d'apt ($apt_v) permet d'utiliser simplement les sources avec "
|
||
alert_httpsPossible+="le protocole https et les dépôts deb.debian.org"
|
||
fi
|
||
# httpredir
|
||
if grep -iq 'httpredir' <<< $sources ; then
|
||
alert_httpredir="ces urls sont obsolètes, préférer http://deb.debian.org/ ou un miroir local: \n\n"
|
||
alert_httpredir+="$(grep 'httpredir' <<< "$sources")"
|
||
fi
|
||
echo -n "◇"
|
||
# extraction qte ugrade, full-upgrade
|
||
stck_upgd=$( LC_ALL=C apt-get upgrade --simulate 2>/dev/null )
|
||
# $1 upgraded, $6 to remove, $10 not upgraded # => qte_upgradable [0]=upgraded, [1]=notUpgraded
|
||
qte_upgradable=($( gawk '/ newly installed/{print $1" "$10}' <<< $stck_upgd )) # tableau
|
||
[ "${qte_upgradable[0]}" ] || qte_upgradable=("-1" "-1") # si erreur
|
||
# upgrade
|
||
[ "${qte_upgradable[0]}" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_upgrade="${qte_upgradable[0]} paquet"$pluriel" à mettre à jour"
|
||
[ "${qte_upgradable[0]}" -eq 0 ] && cmt_upgrade=${cmt_upgrade/0 /aucun }
|
||
cmd_upgrade="apt list --upgradable"
|
||
if [ "${qte_upgradable[0]}" -gt 0 ]; then
|
||
upgrade=$( grep '^Inst' <<< "$stck_upgd" | sort | gawk '{
|
||
sub(/\(/,"",$4); sub(/\/.*/,"",$5); sub(/\[/,"",$3); sub(/\]/,"",$3);
|
||
printf "%-25s source: %-25s %-20s ⇉ %-20s\n",$2,$5,$3,$4 }')
|
||
alert_upgrade="ces paquets peuvent être mis à jour avec: **apt upgrade**"
|
||
elif [ "${qte_upgradable[0]}" -lt 0 ]; then
|
||
upgrade="• erreur apt, les paquets à mettre à jour ne peuvent être déterminés"
|
||
alert_apt="Erreur Apt, commencer par vérifier avec **apt update** (en root)"
|
||
fi
|
||
# full-upgrade
|
||
if [ "${qte_upgradable[1]}" -gt 0 ]; then
|
||
notUpgraded=${stck_upgd%The following packages will be upgraded*} # suppression fin
|
||
notUpgraded=${notUpgraded#*The following packages have been kept back:} # suppression début
|
||
notUpgraded=$( sed '/newly/d' <<< "$notUpgraded" | sort | tr '\n' ' ' )
|
||
notUpgraded=${notUpgraded// / } # suppression espace double
|
||
[ "${qte_upgradable[1]}" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_notUpgraded="${qte_upgradable[1]} paquet"$pluriel" nécessitant une mise à jour profonde)"
|
||
alert_full_upgrade="ces paquets peuvent être mis à jour avec avec: **apt full-upgrade**"
|
||
fi
|
||
echo -n "◇"
|
||
# autoremove
|
||
toRemove=$( LC_ALL=C apt-get autoremove --simulate | grep -E 'Remv | newly installed' )
|
||
toRemove=$( sort <<< $toRemove )
|
||
qte_toRemove=$( gawk '/ newly installed/{ printf $6 }' <<< $toRemove )
|
||
toRemove=$( sed '/newly/d' <<< "$toRemove" ) # suppression ligne état
|
||
[ "$qte_toRemove" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_toRemove="$qte_toRemove paquet"$pluriel" inutile"$pluriel
|
||
[ "$qte_toRemove" -eq 0 ] && cmt_toRemove=${cmt_toRemove/0 /aucun }
|
||
cmd_toRemove="apt autoremove --simulate"
|
||
if [ "$qte_toRemove" -gt 0 ]; then
|
||
toRemove=$( sed -E '/^Remv/!d; s/\[.*\]//g; s/Remv //' <<< $toRemove | tr '\n' ' ' )
|
||
toRemove=${toRemove// / }
|
||
alert_remove="les paquets peuvent être supprimés avec: **apt autoremove --purge** \n\n"
|
||
alert_remove+="vérifier que la liste ne contient pas des applications devenues importantes \n"
|
||
alert_remove+="au besoin, les marquer comme installées manuellement avec apt-mark manual <paquet> \n"
|
||
alert_remove+="ou les installer manuellement avec apt install <paquet>"
|
||
fi
|
||
# autoclean
|
||
echo -n "◇"
|
||
autoclean=$( grep '^Del' <<< $( LC_ALL=C apt-get autoclean --simulate 2>/dev/null ) )
|
||
qte_autoclean=$( f__wcv -l "$autoclean" )
|
||
[ "$qte_autoclean" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_autoclean="$qte_autoclean archive"$pluriel" périmée"$pluriel
|
||
[ "$qte_autoclean" -eq 0 ] && cmt_autoclean=${cmt_autoclean/0 /aucune }
|
||
cmd_autoclean="apt autoclean --simulate"
|
||
if [ "$qte_autoclean" -gt 0 ]; then
|
||
autoclean=$( gawk '{print $2}' <<< $autoclean | sort | tr '\n' ' ' )
|
||
alert_autoclean="ces archives de paquets, sans utilité directe dans le système, "
|
||
alert_autoclean+="peuvent être supprimées avec: **apt autoclean**"
|
||
fi
|
||
# clean
|
||
clean=$( LC_ALL=C LC_ALL=C du -chS /var/cache/apt/archives/ 2>/dev/null )
|
||
size_clean=$( du -ckS /var/cache/apt/archives/ 2>/dev/null | grep -i 'total' ) # affichage en ko
|
||
size_clean=${size_clean%[[:blank:]]total}
|
||
size_cleanH=$( du -chS /var/cache/apt/archives/ 2>/dev/null | grep -i 'total' ) # affichage en human
|
||
size_cleanH=${size_cleanH%[[:blank:]]total}
|
||
qte_clean=$( f__wcv -l "$( ls -1 /var/cache/apt/archives/ )" )
|
||
[ "$qte_clean" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_clean="taille du cache des paquets"
|
||
cmd_clean="du -chS /var/cache/apt/archives/"
|
||
if [ "$size_clean" -gt 200 ]; then # alerte si > à 100 ko (cache pas vide)
|
||
alert_clean="$qte_clean archive"$pluriel" dans le cache de téléchargement des paquets \n"
|
||
alert_clean+="$size_cleanH pourraient être libérés en effaçant ce cache: **apt clean**"
|
||
else # cache vide (72ko à 120ko)
|
||
clean="• cache vide"
|
||
fi
|
||
# paquet non ^ii
|
||
non_ii=$( LC_ALL=C dpkg -l | gawk 'FNR>5 && ! /^i/ {
|
||
printf "%-3s %-20s %-12s",$1,$2,$3; $1=$2=$3=$4=""; printf "%s \n",$0 }' )
|
||
qte_non_ii=$( f__wcv -l "$non_ii" )
|
||
[ "$qte_non_ii" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_non_ii="$qte_non_ii paquet"$pluriel" dans un état non standard (^ii)"
|
||
[ "$qte_non_ii" -eq 0 ] && cmt_non_ii=${cmt_non_ii/0 /aucun }
|
||
cmd_non_ii="dpkg -l | grep -v '^ii'" # dpkg -l | gawk '! /^ii/ {print $0}'
|
||
if [ "$qte_non_ii" -gt 0 ]; then
|
||
# extraction différents états constatés
|
||
while read etat ligne ; do
|
||
stck_etat+="$etat"$'\n'
|
||
done <<< "$non_ii"
|
||
stck_etat=$( sort -u <<< "$stck_etat" ) # tri et dédoublonnage
|
||
non_ii+="\n\n ‣ État souhaité / État du paquet / Drapeaux d'erreur\n"
|
||
for ligne in $stck_etat; do
|
||
[[ ${ligne,,} =~ ^h ]] && non_ii+=" h: hold (à garder) "
|
||
[[ ${ligne,,} =~ ^i ]] && non_ii+=" i: install (à installer) "
|
||
[[ ${ligne,,} =~ ^p ]] && non_ii+=" p: purge (à purger) "
|
||
[[ ${ligne,,} =~ ^r ]] && non_ii+=" r: remove (à supprimer) "
|
||
[[ ${ligne,,} =~ ^u ]] && non_ii+=" u: unknown (inconnu) "
|
||
[[ ${ligne,,} =~ ^.c ]] && non_ii+=" c: config-files (fichiers de configuration) "
|
||
[[ ${ligne,,} =~ ^.f ]] && non_ii+=" f: halF-configured-configured (semi-configuré) "
|
||
[[ ${ligne,,} =~ ^.h ]] && non_ii+=" h: Half-installed (semi-installé) "
|
||
[[ ${ligne,,} =~ ^.i ]] && non_ii+=" i: installed (installé) "
|
||
[[ ${ligne,,} =~ ^.n ]] && non_ii+=" n: not-installed (non installé) "
|
||
[[ ${ligne,,} =~ ^.t ]] && non_ii+=" t: triggers-pending (actions différées en cours) "
|
||
[[ ${ligne,,} =~ ^.u ]] && non_ii+=" u: unpacked (décompressé seulement) "
|
||
[[ ${ligne,,} =~ ^.w ]] && non_ii+=" w: triggers-awaiting (attente actions différées) "
|
||
[[ ${ligne,,} =~ ^..r ]] && non_ii+=" r: (réinstallation requise) " || non_ii+=" / . "
|
||
non_ii+=$'\n'
|
||
done
|
||
non_ii=${non_ii::-1} # suppression $'\n'
|
||
if grep -q '^rc' <<< "$stck_etat"; then
|
||
alert_non_ii="les paquets dans un état 'rc' (fichiers de configuration orphelins) "
|
||
alert_non_ii+="peuvent être purgés avec: \n"
|
||
alert_non_ii+="**dpkg --purge \$(dpkg -l | awk '/^rc/{print \$2}')**"
|
||
fi
|
||
fi
|
||
# deborphan éventuel
|
||
if [ $( f__which deborphan ) ]; then
|
||
deborphan=$( deborphan -P )
|
||
cmd_deborphan="deborphan -P"
|
||
qte_deborphan=$( f__wcv "-l" "$deborphan" )
|
||
[ "$qte_deborphan" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_deborphan="$qte_deborphan bibliothèque"$pluriel" orpheline"$pluriel
|
||
[ "$qte_deborphan" -eq 0 ] && cmt_deborphan=${cmt_deborphan/0 /aucune }
|
||
if [ "$qte_deborphan" -gt 0 ]; then
|
||
alert_deborphan="bibliothèque"$pluriel" orpheline"$pluriel", suppression possible: \n"
|
||
alert_deborphan+="**apt purge \$(deborphan)** \n"
|
||
alert_deborphan+="recherche légère, mais vérifier avant de valider la suppression \n"
|
||
alert_deborphan+="Relancer la commande jusqu'à vidage complet, les bibliothèques pouvant "
|
||
alert_deborphan+="s'installer en cascade"
|
||
fi
|
||
fi
|
||
# paquets figés
|
||
holded=$( apt-mark showhold )
|
||
qte_holded=$( f__wcv "-l" "$holded" )
|
||
[ "$holded" ] && holded=$( sort <<< $holded | tr '\n' ' ' )
|
||
[ "$qte_holded" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_holded="$qte_holded paquet"$pluriel" figé"$pluriel
|
||
[ "$qte_holded" -eq 0 ] && cmt_holded=${cmt_holded/0 /aucun }
|
||
cmd_holded="apt-mark showhold"
|
||
###
|
||
f_pr titre2 "gestion de paquets ${1#*:}"
|
||
f_pr 1 "nombre de paquets installés: **$nb_packages**"
|
||
f_pr 1 "dernière mise à jour apt: **$dateMaj**"
|
||
f_pr 1 "version apt: **$apt_version**"
|
||
f_pr
|
||
f_dspl_alrt "$info_update" "info"
|
||
f_di cmd "$sources" "$cmd_sources" "$cmt_sources"
|
||
f_dspl_alrt "$alert_https" "info"
|
||
f_dspl_alrt "$alert_httpsPossible" "info"
|
||
f_dspl_alrt "$alert_non_list" "info"
|
||
f_dspl_alrt "$alert_httpredir" "info"
|
||
f_di cmd "$apt_prefs" "$cmd_apt_prefs" "$cmt_apt_prefs"
|
||
f_di cmd:vide "$upgrade" "$cmd_upgrade" "$cmt_upgrade"
|
||
f_dspl_alrt "$alert_upgrade" "info"
|
||
f_dspl_alrt "$alert_apt" "alerte"
|
||
f_di var "$notUpgraded" "" "$cmt_notUpgraded"
|
||
f_dspl_alrt "$alert_full_upgrade" "info"
|
||
f_di cmd:vide "$toRemove" "$cmd_toRemove" "$cmt_toRemove"
|
||
f_dspl_alrt "$alert_remove" "info"
|
||
f_di cmd:vide "$autoclean" "$cmd_autoclean" "$cmt_autoclean"
|
||
f_dspl_alrt "$alert_autoclean" "info"
|
||
f_di cmd "$clean" "$cmd_clean" "$cmt_clean"
|
||
f_dspl_alrt "$alert_clean" "info"
|
||
f_di cmd:vide "$non_ii" "$cmd_non_ii" "$cmt_non_ii"
|
||
f_dspl_alrt "$alert_non_ii" "info"
|
||
if [ $( f__which deborphan ) ]; then
|
||
f_di cmd "$deborphan" "$cmd_deborphan" "$cmt_deborphan"
|
||
f_dspl_alrt "$alert_deborphan" "info"
|
||
fi
|
||
f_di cmd:vide "$holded" "$cmd_holded" "$cmt_holded"
|
||
}
|
||
|
||
fi_pkg_x(){ #v2 1/12/2017
|
||
local nb_packages cmd_nbPackages sources cmd_sources holded cmd_holded
|
||
|
||
if [[ ${1%:*} == "dnf" ]]; then # Fedora, RedHat (rpm)
|
||
# http://dnf.readthedocs.io/en/latest/command_ref.html
|
||
# http://landoflinux.com/linux_dnf_command_examples.html
|
||
nb_packages=$( LC_ALL=C dnf list installed 2>/dev/null ) # nb_packages=$( f__wcv -l "$( rpm -qa 2>/dev/null )")
|
||
nb_packages=${nb_packages#*Installed Packages} # suppression début variable jusqu'à Installed...
|
||
cmd_nbPackages="dnf list installed"
|
||
sources=$( f_grep_file "/etc/yum.repos.d/*.repo" )
|
||
cmd_sources="grep -Ersv '^#|^$' /etc/yum.repos.d/*.repo"
|
||
elif [[ ${1%:*} == "pacman" ]]; then # ArchLinux
|
||
nb_packages=$( pacman -Q &>/dev/null ) # pas d'exemple de sortie trouvé
|
||
cmd_nbPackages="pacman -Q"
|
||
sources=$( f_grep_file "/etc/pacman.conf /etc/pacman.d/*" )
|
||
cmd_sources="grep -Ersv '^#|^$' /etc/pacman.conf /etc/pacman.d/*"
|
||
elif [[ ${1%:*} == "pacman-g2" ]]; then # Frugalware
|
||
nb_packages=$( pacman-g2 -Q &>/dev/null ) # pas d'exemple de sortie trouvé
|
||
cmd_nbPackages="pacman-g2 -Q"
|
||
sources=$( f_grep_file "/etc/pacman.conf /etc/pacman.d/*" ) # coup de bluff
|
||
cmd_sources="grep -Ersv '^#|^$' /etc/pacman.conf /etc/pacman.d/*"
|
||
elif [[ ${1%:*} == "portage" ]]; then # Gentoo # Sabayon: + Entropy ?
|
||
nb_packages=$( emerge -ep world &>/dev/null ) # pas d'exemple de sortie trouvé
|
||
cmd_nbPackages="emerge -ep world"
|
||
sources=$( f_grep_file "/etc/portage/repos.conf /etc/portage/repos.conf/*" )
|
||
cmd_sources="grep -Ersv '^#|^$' /etc/portage/repos.conf /etc/portage/repos.conf/*"
|
||
elif [[ ${1%:*} == "slackware" ]]; then # Slackware
|
||
nb_packages=$( ls -1 /var/log/packages 2>/dev/null )
|
||
cmd_nbPackages="wc -l <<< \$(ls -1 /var/log/packages)"
|
||
sources=$( f_grep_file "/etc/slackpkg/mirrors" )
|
||
cmd_sources="grep -Ersv '^#|^$' /etc/slackpkg/mirrors"
|
||
elif [[ ${1%:*} == "zypper" ]]; then # Suse, openSuse
|
||
nb_packages=$( zypper search --installed-only 2>/dev/null | grep '^i' ) # # nb_packages=$( f__wcv -l "$( rpm -qa 2>/dev/null )")
|
||
cmd_nbPackages="zypper search --installed-only"
|
||
sources=$( f_grep_file "/etc/zypp/repos.d/*.repo" )
|
||
cmd_sources="grep -Ersv '^#|^$' /etc/zypp/repos.d/*.repo"
|
||
holded=$( zypper locks 2>/dev/null )
|
||
cmd_holded="zypper locks"
|
||
elif [[ ${1#*:} == "alps" ]]; then # AryaLinux
|
||
nb_packages=$( alps showinstalled &>/dev/null )
|
||
cmd_nbPackages="alps showinstalled"
|
||
elif [[ ${1#*:} == "eopkg" ]]; then # Solus Linux
|
||
nb_packages=$( ls -1 /var/lib/eopkg/package 2>/dev/null )
|
||
nb_packages=$( f__wcv -l "$nb_packages")
|
||
cmd_nbPackages="wc -l <<< \$(ls -1 /var/lib/eopkg/package)"
|
||
elif [[ ${1#*:} == "Guix" ]]; then # Gnu Guix
|
||
nb_packages=$( ls -1 /gnu/store/*/ 2>/dev/null )
|
||
cmd_nbPackages="wc -l <<< \$(ls -1 /gnu/store/*/)"
|
||
elif [[ ${1#*:} == "lvu" ]]; then # LunarLinux
|
||
nb_packages=$( lvu installed 2>/dev/null )
|
||
cmd_nbPackages="lvu installed"
|
||
elif [[ ${1#*:} == "Nix" ]]; then # NixOs
|
||
nb_packages=$( ls -d -1 /nix/store/*/ 2>/dev/null )
|
||
cmd_nbPackages="wc -l <<< \$(ls -1 /nix/store/*/)"
|
||
elif [[ ${1#*:} == "opkg" ]]; then # opkg fork ipkg, ipkg (abandonné) sauf sur Syno?
|
||
nb_packages=$( opkg list-installed 2>/dev/null )
|
||
cmd_nbPackages="opkg list-installed"
|
||
elif [[ ${1#*:} == "Sorcery" ]]; then # SourceMage (sorcerer)
|
||
nb_packages=$( gaze installed 2>/dev/null )
|
||
cmd_nbPackages="gaze installed"
|
||
elif [[ ${1#*:} == "tazpkg" ]]; then # SliTaz
|
||
nb_packages=$( tazpkg list 2>/dev/null )
|
||
cmd_nbPackages="tazpkg list"
|
||
elif [[ ${1#*:} == "TinyCoreExtensions" ]]; then # TinyCoreLinux
|
||
nb_packages=$( tce-status -i 2>/dev/null )
|
||
cmd_nbPackages="tce-status -i"
|
||
sources=$( f_grep_file "/opt/tcemirror" )
|
||
cmd_sources="/opt/tcemirror"
|
||
elif [[ ${1#*:} == "VoidLinux" ]]; then # VoidLinux
|
||
nb_packages=$( xbps-query -l 2>/dev/null )
|
||
cmd_nbPackages="xbps-query"
|
||
sources=$( f_grep_file "/etc/xbps.d/* /usr/share/xbps.d/*" )
|
||
cmd_sources="grep -Ersv '^#|^$' /etc/xbps.d/* /usr/share/xbps.d/*"
|
||
fi
|
||
nb_packages=$( f__wcv -l "$nb_packages" )
|
||
[[ -z "$nb_packages" || "$nb_packages" -le 5 ]] && nb_packages="n/a"
|
||
[[ ${1#*:} == "Inconnue" ]] && unset nb_packages # totalement inconnu
|
||
###
|
||
f_pr titre2 "gestion de paquets ${1#*:}"
|
||
f_di cmd:text "$nb_packages" "$cmd_nbPackages" "nombre de paquets installés"
|
||
f_di cmd "$sources" "$cmd_sources" "sources"
|
||
f_di cmd "$holded" "$cmd_holded" "paquets figés"
|
||
f_di var "$alert_pkg_todo" "aide souhaitée"
|
||
}
|
||
|
||
fi_reseau(){ # 1/12/2017 ( configuration )
|
||
local ip_a iwconfig interfaces route resolv canal_wifi ifx text pluriel
|
||
local alert_ifconfig
|
||
|
||
# ip a & route
|
||
ip_a=$( ip a | sed '/link\/ether/d; /valid_lft/d' ) # filtre sur adr MAC & bail
|
||
# ip_a=$( sed '/inet6.*scope global/d; /inet6.*scope link/d' <<< $ip_a ) # filtre sur inet6 scope global & scope link (fe80::)
|
||
ip_a=$( sed '/inet6.*/d' <<< $ip_a ) # filtre sur inet6)
|
||
route=$( ip route show )
|
||
# interfaces & resolv
|
||
interfaces=$( f_grep_file "/etc/network/interfaces*" )
|
||
interfaces=$( sed -E 's/wpa-psk [[:graph:]]+/wpa-psk <WPA key removed>/; s/:/: /' <<< $interfaces )
|
||
resolv=$( f_grep_file "/etc/resolv.conf" "notitre" )
|
||
# iwconfig
|
||
if [ $( f__which iwconfig ) ]; then #paquet wireless-tools requis
|
||
iwconfig=$( LC_ALL=C iwconfig 2>&1 | grep -v 'no wireless extensions' | grep -v '^[[:space:]]*$' )
|
||
fi
|
||
# iwlist
|
||
if [ $( f__which iwlist ) ]; then # canal wifi utilisé; /sbin, paquet wireless-tools requis
|
||
canal_wifi=$( LC_ALL=C iwlist chan 2>&1 | grep 'Current Frequency' | grep -Eio 'channel [0-9]+' )
|
||
fi
|
||
# network manager
|
||
netmgrpaths=("/usr/sbin/NetworkManager" "/usr/sbin/wicd" "/usr/sbin/connmand") # thanks wireless-info
|
||
netmgrnames=("NetworkManager" "Wicd" "ConnMan")
|
||
for ifx in "${!netmgrpaths[@]}"; do
|
||
[ -e "${netmgrpaths[$ifx]}" ] && netmgrinst+=${netmgrnames[$ifx]}
|
||
if [ $( ps -ef | grep -c ${netmgrpaths[$ifx]} ) -ge 2 ]; then
|
||
netmgrrun+="$(ps -ef | grep -o "${netmgrpaths[$ifx]}.*$" | head -n 1)"
|
||
fi
|
||
done
|
||
if [ $( f__which ifconfig ) ] ; then
|
||
alert_ifconfig="ifconfig [net-tools](https://github.com/giftnuss/net-tools) est un projet abandonné "
|
||
alert_ifconfig+="depuis des années. iproute2 (linuxfoundation) le remplace."
|
||
fi
|
||
[ "$fg_ip" ] || figet_ip
|
||
###
|
||
f_pr titre2 "configuration"
|
||
# ip locales avec type
|
||
[ $(f__wcv "-l" "$fg_ip_tp") -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_di sans "$fg_ip_tp" "" "IP locale"$plurielD
|
||
f_pr 1 "les adresses Mac peuvent être affichées avec \`$DIRNAME""getInfo --mac\`"
|
||
f_pr 1 "l'IP publique peut être connue avec: \`$DIRNAME""getInfo --ip\`"
|
||
f_pr
|
||
# gateways
|
||
[ $(f__wcv "-l" "$fg_gws") -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_di sans "$fg_gws" "" "Passerelle"$pluriel
|
||
# interface se sortie
|
||
if [ $(wc -w <<< $fg_ifn) -gt 1 ]; then
|
||
f_di sans "$fg_ifn_prior" "" "interface de sortie"
|
||
fi
|
||
# ip a & route & interface & resolv
|
||
f_di cmd "$ip_a" "ip address" "sans ipV6 et sans adresses MAC"
|
||
f_di cmd "$route" "ip route show"
|
||
f_di cmd "$interfaces" "grep -EHrsv '#|^$' /etc/network/interfaces*" "configuration manuelle"
|
||
f_di cmd "$resolv" "cat /etc/resolv.conf" "serveurs de noms DNS utilisés"
|
||
# iwconfig & iwlist
|
||
f_di cmd "$iwconfig" "iwconfig" "état carte wifi"
|
||
if [ "$canal_wifi" ]; then
|
||
f_di cmd "$canal_wifi" "iwlist chan | grep 'Current Frequency' | grep -Eio 'channel [0-9]+'" \
|
||
"canal wifi utilisé"
|
||
f_pr 1 "la configuration ssid utilisée peut être connue (si NetworkManager) avec \n \`$DIRNAME""getInfo --ssid\`"
|
||
f_pr
|
||
fi
|
||
# network manager
|
||
f_pr 1 "gestionnaire de réseau"
|
||
if [ "$netmgrinst" ]; then
|
||
[ $(wc -w <<< $netmgrinst) -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr 2 "installé"$pluriel": **$netmgrinst**"
|
||
f_pr 2 "en fonctionnement: **$netmgrrun**"
|
||
else
|
||
f_pr 2 "non trouvé parmi: ${netmgrnames[@]}"
|
||
fi
|
||
f_dspl_alrt "$alert_ifconfig" "info"
|
||
f_pr flush
|
||
}
|
||
|
||
fi_serial(){ #v2 1/12/2017
|
||
local chassis_serial machineId text
|
||
|
||
[ "$fg_nb_disk" ] || figet_disk
|
||
[ "$fg_nb_batt" ] || figet_batt
|
||
chassis_serial=$( cat /sys/class/dmi/id/chassis_serial 2>/dev/null )
|
||
[ "$chassis_serial" ] || chassis_serial="n/a"
|
||
machineId=$( cat /etc/machine-id 2>/dev/null )
|
||
[ "$machineId" ] || machineId="n/a"
|
||
###
|
||
f_pr titre1 "$BOLD""ID MAchine $BLUE$machineId$STD"
|
||
f_pr
|
||
f_pr 1 "$BOLD""N° Série:$STD"
|
||
f_pr
|
||
f_pr 2 "$GREEN""Disques:"
|
||
f_pr l3 "$BLUE$fg_disk_serial$STD" '[ "$fg_disk_serial" ]'
|
||
f_pr
|
||
f_pr 2 "$GREEN""Batteries:"
|
||
f_pr l3 "$BLUE$fg_batt_serial$STD"
|
||
f_pr
|
||
f_pr 2 "$GREEN""Chassis:"
|
||
f_pr l3 "$BLUE$chassis_serial$STD"
|
||
echo -e "$text\n"
|
||
}
|
||
|
||
fi_ssid(){ #v2 1/12/2017
|
||
local nm_ssid text
|
||
local fileOutput="/tmp/$RANDOM-$RANDOM" # ré-assigne sortie pour f_di
|
||
|
||
[ "$EUID" -eq 0 ] || f__error "Root requis"
|
||
[ $( f__which nmcli ) ] || f__error "NetworkManager requis"
|
||
nm_ssid=$( f_grep_file "/etc/NetworkManager/system-connections/*" "lignevide" )
|
||
###
|
||
f__info "$RED""Attention:$BLUE la clé du réseau wifi est visible"
|
||
f_pr titre1 "configuration(s) ssid networkmanager"
|
||
f_di cmd "$nm_ssid" "grep -Ersv '#|^$' /etc/NetworkManager/system-connections/*"
|
||
f_pr flush
|
||
f_dspl_md "$fileOutput" "marge"
|
||
rm "$fileOutput"
|
||
}
|
||
|
||
fi_system(){ # 2/12/2017
|
||
local mbr uname bootImage initDaemon date_install ligne lastboot uptime charge serverX pluriel text
|
||
local alimentation alim_total
|
||
|
||
# appels fonctions externes
|
||
[ "$fg_nb_batt" ] || figet_batt
|
||
[ "$fg_cpu" ] || figet_cpu
|
||
[ "$fg_de" ] || figet_de
|
||
[ "$fg_nb_disk" ] || figet_disk
|
||
[ "$fg_distrib" ] || figet_distrib
|
||
[ "$fg_dsp_mngr" ] || figet_dm
|
||
[ "$fg_dmi" ] || figet_dmi
|
||
[ "$fg_resolution" ] || figet_screen
|
||
[ "$fg_shell" ] || figet_shell
|
||
[ "$fg_wm" ] || figet_wm
|
||
[ "$fe_cards_audio" ] || fi_audio "silent"
|
||
[ "$fe_cards_bluez" ] || fi_bluez "silent"
|
||
[ "$fg_gpu" ] || fi_gpu "silent"
|
||
[ "$fe_cards_reseau" ] || fi_net "silent"
|
||
[ "$fu_archi" ] || f__architecture
|
||
echo -n "ø"
|
||
# divers système
|
||
[ -d /sys/firmware/efi ] && mbr="EFI" || mbr="Legacy (mbr)"
|
||
uname=$( uname -rmo )
|
||
bootImage=$( gawk '{print $1}{i=2; while (i <= NF-1) { print " ",$i; i++}}' /proc/cmdline )
|
||
initDaemon=$( ps -p1 | gawk 'FNR==2 {print $4}' ) #? ps -ax | gawk '$1==1' ou ps -p1 | gawk '$1==1'
|
||
if [[ "$initDaemon" == "systemd" && $( f__which systemd ) ]]; then
|
||
initDaemon=$( systemd --version )
|
||
initDaemon=${initDaemon%%[[:space:]]\+*}
|
||
initDaemon=${initDaemon/systemd /systemd v}
|
||
fi
|
||
initDaemon=${initDaemon^}
|
||
while read ligne; do
|
||
date_install=$ligne
|
||
done <<< $( ls -lt --time-style '+FORMAT %d/%m/%Y' / )
|
||
[[ "$date_install" =~ .*([0-9]{2}/[0-9]{2}/[0-9]{4}).* ]] && date_install=${BASH_REMATCH[1]}
|
||
# lastboot="$(last -n 1 --time-format iso reboot | gawk 'FNR==1 {sub(/T/," ",$5);print $5}')" # remis à jours en début de mois ?!!
|
||
lastboot=$( date -r /var/run/utmp '+%d/%m/%Y %H:%M %z' )
|
||
uptime=$( LC_ALL=C uptime )
|
||
charge=${uptime/*average: } # suppression jusqu'à 'average: '
|
||
charge=${charge//, / } # remplacement global ', ' par ' '
|
||
charge=${charge//,/.} # remplacement global , par .
|
||
uptime=${uptime%%, *} # uptime -p parfois inexistant (alpine), suppression à la fin de ',[blancs]*' -> conservation premier 'champs' ifs ', '
|
||
uptime=${uptime/*up } # suppression jusqu'à 'up '
|
||
uptime=${uptime//weeks/semaines} # remplacement global
|
||
uptime=${uptime//week/semaine} # remplacement global
|
||
uptime=${uptime//days/jours} # remplacement global
|
||
uptime=${uptime//day/jour} # remplacement global
|
||
uptime=${uptime//hours/h} # remplacement global
|
||
uptime=${uptime//hour/h} # remplacement global
|
||
uptime=${uptime//minutes/mn} # remplacement global
|
||
uptime=${uptime//minute/mn} # remplacement global
|
||
# server X
|
||
serverX="${XDG_SESSION_TYPE^}" # retourne wayland normalement si c'est la cas
|
||
serverX+=" $fe_Xorg"
|
||
[[ -z "$serverX" && "$ENV_DISPLAY" ]] && serverX+=":no DISPLAY"
|
||
[[ -z "$serverX" && "$ENV_SSH" ]] && serverX+=":ssh"
|
||
[ -z "$serverX" ] && serverX="n/a"
|
||
# alimentation
|
||
if [ $( grep -c 'AC' <<< $(ls /sys/class/power_supply/ 2>/dev/null) ) -gt 0 ]; then
|
||
alim_total=$( grep -cs . <<< $(ls /sys/class/power_supply/AC*/online) )
|
||
alimentation=$( gawk -v "alim_total=$alim_total" '
|
||
{ alim_on=sprintf("%d", $1); if (alim_on>1) pllo="s" }
|
||
END { if ( alim_total > 1 ) pllt="s"; printf alim_total " alimentation" pllt
|
||
if ( alim_total != alim_on ) print ", " alim_on " branchée" pllo; else print "" }
|
||
' /sys/class/power_supply/AC*/online )
|
||
fi
|
||
###
|
||
[ "$ORIGIN" ] && f_pr titre2 "système"
|
||
f_pr l "$( sed -E 's/(.*)/**\1** /' <<<$fg_dmi )" # en gras
|
||
f_pr
|
||
f_pr 1 "CPU"
|
||
f_pr 2 "**$( sed -n '1p' <<< $fg_cpu )**"
|
||
f_pr 1 "Vidéo"
|
||
f_pr 2 "$( sed -E 's/(.*)/**\1**/' <<<$fg_gpu )" '[ "$fg_gpu" ]'
|
||
f_pr 2 "pas de carte graphique détectée" '[ "$fe_nb_gpu" -eq 0 ]'
|
||
f_pr 1 "Réseau"
|
||
f_pr 2 "$( sed -E 's/(.*)/**\1**/' <<<$fe_cards_reseau )" '[ "$fe_cards_reseau" ]'
|
||
f_pr 2 "pas de carte réseau détectée" '[ "$fe_nb_reseau" -eq 0 ]'
|
||
f_pr 1 "Audio"
|
||
f_pr 2 "$( sed -E 's/(.*)/**\1**/' <<<$fe_cards_audio )" '[ "$fe_cards_audio" ]'
|
||
f_pr 2 "pas de carte réseau détectée" '[ "$fe_nb_audio" -eq 0 ]'
|
||
f_pr
|
||
f_pr l '```'
|
||
f_pr l1 "$fg_distrib"
|
||
f_pr l2 "$uname"
|
||
f_pr l2 "boot: $mbr"
|
||
f_pr l2 "architecture système: $fu_archi"
|
||
f_pr l2 "date d'installation: $date_install"
|
||
f_pr l2 "démon d'initialisation: $initDaemon"
|
||
f_pr l2 "shell actif: $fg_shell"
|
||
[ "$( f__wcv -w "$fg_shells" )" ] && pluriel="s" || unset pluriel
|
||
f_pr l2 "shell"$pluriel" installé"$pluriel": $fg_shells"
|
||
f_pr l2 "$bootImage"
|
||
f_pr
|
||
f_pr l1 "Environnement"
|
||
f_pr l2 "serveur d'affichage: $serverX"
|
||
f_pr l2 "nombre d'écrans: $fg_nb_screen"
|
||
[ "$(f__wcv "-wv" "$fg_resolution" "pixels")" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l2 "résolution"$pluriel": $fg_resolution"
|
||
[ "$(wc -w <<< $fg_dsp_mngr)" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l2 "display manager"$pluriel": $fg_dsp_mngr"
|
||
f_pr l2 "display manager actif: $fg_dsp_mngr_actif" '[ "$fg_dsp_mngr_actif" != "$fg_dsp_mngr" ]'
|
||
f_pr l2 "desktop (DE): $fg_de"
|
||
f_pr l2 "panel: $fg_de_panel" '[ "$fg_de_panel" ]'
|
||
f_pr l2 "window manager: $fg_wm"
|
||
f_pr
|
||
f_pr l1 "Matériel"
|
||
[ "$fg_nb_cpu" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l2 "$fg_nb_cpu processeur"$pluriel" $fg_cpu_arch"
|
||
[ "$fe_nb_bluez" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f_pr l2 "$fe_nb_bluez carte"$pluriel" bluetooth ($fe_cards_bluez)" '[ "$fe_nb_bluez" -gt 0 ]'
|
||
f_pr l2 "$alimentation" '[ "$alimentation" ]'
|
||
[ "$fg_nb_batt" -gt "1" ] && pluriel="s" || unset pluriel
|
||
f_pr l2 "$fg_nb_batt batterie"$pluriel" présente"$pluriel":" '[ "$fg_batt" ]'
|
||
f_pr l3 "$(sed -n '1p' <<< $fg_batt)" '[ "$fg_batt" ]'
|
||
f_pr l '```'
|
||
f_pr
|
||
f_pr 1 "$( sed -E 's/^(.*: )(.*)/\1**\2**/' <<<$fg_disk_part_fix_tot )" '[ "$fg_disk_part_fix_tot" ]'
|
||
f_pr 1 "dernier boot: **$lastboot**, il y a **$uptime**"
|
||
[ "$fg_nb_threads" -gt "1" ] && pluriel="s" || unset pluriel
|
||
f_pr 1 "charge système depuis les 1, 5 et 15 dernières minutes: **$charge** ($fg_nb_threads thread"$pluriel")"
|
||
f_pr flush
|
||
}
|
||
|
||
fi_system_analyse(){ #v 2/12/2017
|
||
[ $( f__which systemd ) ] || return 0 # pas systemd
|
||
local bootTime cmd_bootTime cmt_bootTime pluriel text
|
||
local srvcFail cmd_srvcFail cmt_srvcFail qte_srvcFail isrvc srvcFail_list info_services
|
||
local bootBlame cmd_bootBlame cmt_bootBlame bootCritic cmd_bootCritic cmt_bootCritic
|
||
local bootGraph cmd_bootGraph cmt_bootGraph file="/tmp/getInfo-graph.svg"
|
||
local alert_srvcFail
|
||
|
||
# durée du précédent boot
|
||
bootTime=$( LC_ALL=C systemd-analyze time )
|
||
bootTime=${bootTime/Startup finished in /Durée de boot: }
|
||
bootTime=${bootTime/userspace/espace utilisateur}
|
||
cmd_bootTime="systemd-analyze time"
|
||
cmt_bootTime="durée du boot, avant interface graphique"
|
||
# services en erreur
|
||
# srvcFail=$( systemctl --state=active,failed | grep -cE 'error|not-found|failed' )
|
||
srvcFail=$( LC_ALL=C systemctl --state=active,failed | gawk '
|
||
/error|not-found|failed/ { sub(/●|*/,"");
|
||
printf "%-50s %-11s %-8s %-8s %s",$1,$2,$3,$4,$5; $1=$2=$3=$4=$5=""; print $0}' )
|
||
cmd_srvcFail="systemctl --state=active,failed | grep -E 'error|not-found|failed'"
|
||
qte_srvcFail=$( f__wcv -l $srvcFail )
|
||
[ "$qte_srvcFail" -gt 1 ] && pluriel="s" || unset pluriel
|
||
cmt_srvcFail="service"$pluriel" en erreur"
|
||
if [ "$qte_srvcFail" -gt 0 ]; then
|
||
alert_srvcFail="service"$pluriel" en erreur, statut: \n\n"
|
||
srvcFail_list=$( gawk '{print $1}' <<< "$srvcFail" )
|
||
for isrvc in $srvcFail_list; do
|
||
alert_srvcFail+="\`systemctl status $isrvc\` \n"
|
||
alert_srvcFail+='```\n'
|
||
alert_srvcFail+="$( systemctl status $isrvc 2>&1 ) \n"
|
||
alert_srvcFail+='```\n'
|
||
done
|
||
alert_srvcFail=${alert_srvcFail//●}
|
||
srvcFail=$( printf "%-50s %-11s %-8s %-8s %s" Unit Load Active Sub Description )$'\n'"$srvcFail"
|
||
fi
|
||
info_services="voir tous les services: **systemctl list-units --type=service | pager**"
|
||
# détail par service
|
||
bootBlame=$( LC_ALL=C systemd-analyze blame | head -n 20 )
|
||
cmd_bootBlame="systemd-analyze blame | head -n 20"
|
||
cmt_bootBlame="détail par service"
|
||
# services critiques ralentisseurs
|
||
bootCritic=$( LC_ALL=C systemd-analyze critical-chain )
|
||
bootCritic=${bootCritic/The time after the unit is active or started is printed after the \"@\" character./ @: temps auquel l\'unité est active ou démarrée}
|
||
bootCritic=${bootCritic/The time the unit takes to start is printed after the \"+\" character./ +: temps que l\'unité prend pour démarrer}
|
||
cmd_bootCritic="systemd-analyze critical-chain"
|
||
cmt_bootCritic="services critiques ralentisseurs"
|
||
# génération graphique
|
||
if [[ "$wayland" && "$EUID" -eq 0 ]]; then # évite erreur $DISPLAY en root wayland
|
||
bootGraph="n/a en root sous wayland"
|
||
else
|
||
touch "$file" 2>/dev/null
|
||
[ -w "$file" ] || file="/tmp/getInfo-graph-$RANDOM.svg"
|
||
systemd-analyze plot > "$file" 2>/dev/null
|
||
chown $fu_user: "$file"
|
||
bootGraph="en console: **xdg-open $file** \n"
|
||
bootGraph+="* dans un navigateur: copier/coller ce lien dans la barre d'adresses "
|
||
bootGraph+="file:///$file \n" # résultat avec 4 /, ok
|
||
fi
|
||
# un lien local ne s'ouvrira pas automatiquement :( : http://kb.mozillazine.org/Links_to_local_pages_do_not_work
|
||
cmd_bootGraph="systemd-analyze plot > $file ; xdg-open graph.svg"
|
||
cmt_bootGraph="graph durées et ordre de chargement des services"
|
||
###
|
||
f_pr titre2 "analyse boot systemd"
|
||
f_pr 1 "pas de service en erreur" '[ -z "$srvcFail" ]'
|
||
f_di cmd "$bootTime" "$cmd_bootTime" "$cmt_bootTime"
|
||
f_di cmd "$srvcFail" "$cmd_srvcFail" "$cmt_srvcFail"
|
||
f_dspl_alrt "$info_services" "info"
|
||
f_dspl_alrt "$alert_srvcFail" "alert"
|
||
f_di cmd "$bootBlame" "$cmd_bootBlame" "$cmt_bootBlame"
|
||
f_di cmd "$bootCritic" "$cmd_bootCritic" "$cmt_bootCritic"
|
||
f_di cmd:text "$bootGraph" "$cmd_bootGraph" "$cmt_bootGraph"
|
||
}
|
||
|
||
fi_usb(){ # 1/12/2017
|
||
local lsusb lsusb_t text
|
||
|
||
lsusb=$( lsusb )
|
||
lsusb_t=$( lsusb -t )
|
||
[ "$lsusb" ] || return 0
|
||
###
|
||
f_pr titre2 "USB"
|
||
f_di cmd "$lsusb" "lsusb"
|
||
f_di cmd "$lsusb_t" "lsusb -t"
|
||
}
|
||
|
||
fi_vrms(){ # 1/12/2017
|
||
local vrms non_free contrib total text pluriel tempo
|
||
|
||
[ $( f__which vrms ) ] || return 0
|
||
vrms=$( vrms )
|
||
non_free=$(( $( sed -En 's/([0-9]+) non-free packages,.*/\1/p' <<< "$vrms" ) ))
|
||
contrib=$(( $( sed -En 's/([0-9]+) contrib packages,.*/\1/p' <<< "$vrms" ) ))
|
||
if [[ "$non_free" -gt 0 || "$contrib" -gt 0 ]]; then
|
||
[ "$non_free" -gt 1 ] && pluriel="s" || unset pluriel
|
||
vrms=$( sed -E "s/Non-free packages installed on.*/$non_free paquet$pluriel non libre$pluriel installé$pluriel:/
|
||
" <<< "$vrms" )
|
||
[ "$contrib" -gt 1 ] && pluriel="s" || unset pluriel
|
||
vrms=$( sed -E "s/Contrib packages installed on.*/$contrib paquet$pluriel contrib installé$pluriel:/
|
||
" <<< "$vrms" )
|
||
vrms=$( sed -E '/[0-9]+ non-free packages,/d; /[0-9]+ contrib packages,/d;
|
||
/^[[:space:]]*$/d' <<< $vrms )
|
||
elif grep -iq 'proud' <<< "$vrms" ; then
|
||
tempo="Aucun paquet non libre ou contrib installé sur ce système \n\t\t **rms serait fier ☺**"
|
||
vrms=$( sed -E "s/.*rms would be proud.*/$tempo/" <<< "$vrms" )
|
||
fi
|
||
###
|
||
f_pr titre2 "paquets non-libres"
|
||
f_di cmd "$vrms" "vrms" "détection des paquets non libres par RMS"
|
||
f_pr flush
|
||
}
|
||
|
||
# informations batterie(s), assigne $fg_nb_batt $fg_batt $fg_batt_serial
|
||
figet_batt(){ #v2 11/11/2017
|
||
local batt_detail batt_nb batt_unit batt_capa_design batt_capa_full batt_capa_now batt_conso
|
||
local batt_volt_min batt_volt_now batt_status batt_cycle alert_batt_alarm
|
||
local batt_sante batt_restant tempo batRep ibat uevent
|
||
if [ ! -d /sys/class/power_supply ]; then # anciennes interfaces ou inconnu
|
||
[ -d /proc/acpi/battery ] && batt_detail="ancienne interface ACPI non gérée (obsolète)"
|
||
[ -e /proc/apm ] && batt_detail="anciennes batteries APM non gérées (obolète)"
|
||
[ "$batt_detail" ] || batt_detail="répertoire power_supply inaccessible"
|
||
batt_nb="-1"
|
||
return 1
|
||
fi
|
||
[ "$(grep -c 'BAT' <<< $(ls /sys/class/power_supply/ 2>/dev/null))" -gt 0 ] || return 0
|
||
batt_nb="$(grep -i 'Battery' /sys/class/power_supply/*/type | grep -c .)"
|
||
[ "$batt_nb" ] || return
|
||
batRep="/sys/class/power_supply"
|
||
unset batt_detail
|
||
for ibat in $(ls $batRep); do
|
||
grep -qi 'Battery' "$batRep/$ibat/type" || continue # plus loin si non batterie
|
||
[ -e "$batRep/$ibat/uevent" ] || batt_detail="$ibat: **uevent** incorrect"
|
||
[ -e "$batRep/$ibat/uevent" ] || continue
|
||
uevent="$(grep -s . $batRep/$ibat/uevent)"
|
||
# extractions valeur de calcul selon type
|
||
if grep -q 'POWER_SUPPLY_CHARGE_' <<< $uevent ; then
|
||
batt_unit="mAh"
|
||
batt_capa_design="$(gawk -F '=' '/POWER_SUPPLY_CHARGE_FULL_DESIGN=/ {printf "%d", $2/1000}' <<< $uevent)" # mA
|
||
batt_capa_full="$(gawk -F '=' '/POWER_SUPPLY_CHARGE_FULL=/ {printf "%d", $2/1000}' <<< $uevent)" # mA
|
||
batt_capa_now="$(gawk -F '=' '/POWER_SUPPLY_CHARGE_NOW=/ {printf "%d", $2/1000}' <<< $uevent)" # mA
|
||
batt_conso="$(gawk -F '=' '/POWER_SUPPLY_CURRENT_NOW=/ {printf "%d", $2/1000}' <<< $uevent)" # mA
|
||
elif grep -q 'POWER_SUPPLY_ENERGY_' <<< $uevent ; then
|
||
batt_unit="Wh"
|
||
batt_capa_design="$(gawk -F '=' '/POWER_SUPPLY_ENERGY_FULL_DESIGN=/ {printf "%.2f", $2/1000000}' <<< $uevent)" # W
|
||
batt_capa_full="$(gawk -F '=' '/POWER_SUPPLY_ENERGY_FULL=/ {printf "%.2f", $2/1000000}' <<< $uevent)" # W
|
||
batt_capa_now="$(gawk -F '=' '/POWER_SUPPLY_ENERGY_NOW=/ {printf "%.2f", $2/1000000}' <<< $uevent)" # W
|
||
batt_conso="$(gawk -F '=' '/POWER_SUPPLY_POWER_NOW=/ {printf "%.2f", $2/1000000}' <<< $uevent)" # W
|
||
fi
|
||
# extractions simples
|
||
batt_volt_min="$(gawk -F '=' '/POWER_SUPPLY_VOLTAGE_MIN_DESIGN=/ {printf "%.2f", $2/1000000}' <<< $uevent)" # V
|
||
batt_volt_now="$(gawk -F '=' '/POWER_SUPPLY_VOLTAGE_NOW=/ {printf "%.2f", $2/1000000}' <<< $uevent)" # V
|
||
batt_status="$(gawk -F '=' '/POWER_SUPPLY_STATUS=/ {print $2}' <<< $uevent)"
|
||
batt_cycle="$(gawk -F '=' '/POWER_SUPPLY_CYCLE_COUNT=/ {print $2}' <<< $uevent)"
|
||
fg_batt_serial="$(gawk -F '=' '/POWER_SUPPLY_SERIAL_NUMBER=/ {sub(/^ | $|0/,"",$2); print $2}' <<< $uevent)"
|
||
alert_batt_alarm="$(cat $batRep/$ibat/alarm 2>/dev/null)"
|
||
[ "$alert_batt_alarm" == "0" ] && unset alert_batt_alarm || alert_batt_alarm="$ibat: $alert_batt_alarm"
|
||
# calculs
|
||
batt_sante="$(gawk '$1 != "na" && $2 != "" && $2 != 0 {printf "%.1f", $1/$2*100}' <<< "$batt_capa_full $batt_capa_design")"
|
||
if [[ "$batt_status" == "Full" || "$batt_status" == "Unknown" ]]; then
|
||
batt_restant="totalement chargée"
|
||
elif [ "$batt_status" == "Discharging" ]; then
|
||
batt_restant="en décharge, reste approximativement: "
|
||
tempo="$(gawk '$1+$2 != "" && $2!=0 {print $1*0.9/$2}' <<< "$batt_capa_now $batt_conso")"
|
||
elif [ "$batt_status" == "Charging" ]; then
|
||
batt_restant="en charge, reste approximativement: "
|
||
tempo="$(gawk '$1+$2+$3 != "" && $3 != 0 {print ($1-$2)/$3}' <<< "$batt_capa_full $batt_capa_now $batt_conso")"
|
||
fi
|
||
batt_restant+="$(gawk '$1 != "" {printf "%d h %02d mn \n", $1, $1*60%60}' <<< $tempo) "
|
||
# mise en forme pour sortie, séparateur milliers
|
||
if [ "$batt_unit" == "mAh" ]; then
|
||
batt_capa_design="$(printf "%'d" $batt_capa_design)"
|
||
batt_capa_full="$(printf "%'d" $batt_capa_full)"
|
||
batt_conso="$(printf "%'d" $batt_conso)"
|
||
batt_capa_now="$(printf "%'d" $batt_capa_now)"
|
||
fi
|
||
# sortie
|
||
# ligne 1 && n° série
|
||
batt_detail+="$ibat: $(cat $batRep/$ibat/manufacturer 2>/dev/null) "
|
||
batt_detail+="($(cat $batRep/$ibat/model_name 2>/dev/null)) $(cat $batRep/$ibat/technology 2>/dev/null), "
|
||
batt_detail+="$batt_capa_design$batt_unit - $batt_volt_min""V / $batt_volt_now""V (mini/actuel)"
|
||
[ "$(xargs <<< $fg_batt_serial)" ] && fg_batt_serial="$batt_detail, n° série: $fg_batt_serial" || fg_batt_serial="n/a"
|
||
[ "$batt_cycle" != "0" ] && batt_detail+=", $batt_cycle cycles "$'\n' || batt_detail+=" "$'\n' #ln 1fin
|
||
# ligne 2
|
||
[ "$batt_capa_full" ] && batt_detail+="pleine charge effective: $batt_capa_full$batt_unit, "
|
||
batt_detail+="pleine charge théorique: $batt_capa_design$batt_unit => "
|
||
if [[ "$batt_conso" != "0" && "$batt_conso" != "0.00" ]]; then # conso éventuelle
|
||
batt_restant+="(consommation en cours: $batt_conso$(sed 's/h//' <<< $batt_unit), "
|
||
batt_restant+="charge actuelle: $batt_capa_now$batt_unit)"
|
||
fi
|
||
[ "$batt_sante" ] && batt_detail+="$batt_sante% (indicateur) "$'\n' #ln 2fin
|
||
# ligne 3
|
||
[ "$batt_restant" ] && batt_detail+="$batt_restant "$'\n' #ln 3fin
|
||
# alertes batterie
|
||
# ligne 4 éventuelle (alarme batterie)
|
||
[ "$alert_batt_alarm" ] && batt_detail+="**batterie en alarme** $alert_batt_alarm "$'\n' #[ln 4]
|
||
# lignes 5 alertes
|
||
if [ "$batt_capa_design" == "$batt_capa_full" ] && [ "$batt_volt_min" == "$batt_volt_now" ]; then
|
||
batt_detail+="les pleines charges et les voltages sont incohérents, batterie "
|
||
batt_detail+="mal gérée ou batterie HS? "$'\n' #[ln 5]
|
||
fi
|
||
if [ "$(gawk '{printf "%d", $1}' <<< $batt_sante)" -lt 50 ] && [[ "$batt_status" == "Full" || "$batt_status" == "Unknown" ]]; then
|
||
batt_detail+="batterie très mal chargée (moins de 50%): mauvais état? "$'\n' #[ln 5]
|
||
fi
|
||
done
|
||
fg_nb_batt="$batt_nb"
|
||
[ "$batt_detail" ] && fg_batt=${batt_detail::-1} # suppression dernier $'\n'
|
||
[ "$(xargs <<< $fg_batt_serial)" ] || fg_batt_serial+="n/a"
|
||
}
|
||
|
||
# assigne $fg_cpu (description cpu), fg_nb_threads, $fg_cpu_arch, $fg_uarch, $fg_vendor=AMD|Intel, $fg_nb_cpu
|
||
figet_cpu(){ #v2 1/12/2017
|
||
local cpuinfo speedNom speedMax speedMin speedCpu descrCpu cpu1 cpu2 cpu3
|
||
cpuinfo="$(cat /proc/cpuinfo)"
|
||
# speed
|
||
speedNom=$( gawk -F ':' '
|
||
/cpu MHz/ { printf "%.2f", $2/1000;exit }' <<< "$cpuinfo" )
|
||
speedMax=$( gawk '
|
||
{ printf "%.2f", $1/1000000 }' /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq 2>/dev/null )
|
||
speedMin=$( gawk '
|
||
{printf "%.2f", $1/1000000}' /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq 2>/dev/null )
|
||
speedCpu=""
|
||
if [ "$speedMin" ]; then
|
||
speedCpu+="$speedMin/"
|
||
descrCpu+="fréq. min/"
|
||
fi
|
||
if [ "$speedNom" ]; then
|
||
speedCpu+="$speedNom"
|
||
descrCpu+="nom"
|
||
fi
|
||
if [[ "$speedMax" && "$speedMax" != "$speedNom" ]]; then
|
||
speedCpu+="/$speedMax"
|
||
descrCpu+="/max"
|
||
fi
|
||
[ "$speedCpu" ] && speedCpu=$(printf "%sGHz" $speedCpu)
|
||
[ "$speedCpu" ] || speedCpu=$(gawk -F '@' '/model name/ {sub(/^ | $/,"",$2); print $2;exit}' <<< "$cpuinfo")
|
||
# motifs?: Processor Dual-Core Quad-Core Six-Core Eight-Core Core 'with Radeon * Graphics'
|
||
# nb proc
|
||
fg_nb_cpu=$(
|
||
gawk -F ':|@' '
|
||
/^physical id/ { if ($2+1 != nbCpu) nbCpu=$2+1 }
|
||
END { printf nbCpu}
|
||
' <<< "$cpuinfo" )
|
||
# traitement fg_cpu
|
||
cpu1=$(
|
||
gawk -v "speedCpu=$speedCpu" -F ':|@' '
|
||
/^model name/ { gsub(/^ | *$|\(R\)|\(TM\)|\(r\)|\(tm\)|CPU/,"",$2); gsub(/ /," ",$2); cpu=$2 }
|
||
/^physical id/ { if ($2+1 != nbCpu) nbCpu=$2+1 }
|
||
/cpu cores/ { procCore=sprintf("%d",$2); if (procCore>1) pllc="s" }
|
||
/siblings/ { procThread=sprintf("%d",$2); if (procThread>1) pllt="s" }
|
||
/microcode/ { sub(/^ /,"",$2); microCode=$2 }
|
||
END {
|
||
printf nbCpu" x "cpu " (" procCore "core" pllc ", " procThread "thread" pllt;
|
||
print ") {" speedCpu "} microcode:" microCode
|
||
}' <<< "$cpuinfo "
|
||
)
|
||
cpu2=$(
|
||
gawk -v "descrCpu=$descrCpu" -F ':' '
|
||
/^vendor_id/{gsub(/ /,"");gsub(/AuthenticAMD/,"AMD");gsub(/GenuineIntel/,"Intel");vendor=$2}
|
||
/^cpu family/{family=$2}
|
||
/^model[^ ]/{model=$2}; /^stepping/{rev=$2}
|
||
END {
|
||
code=sprintf("{0x%.2X|0x%.2X}",family,model);
|
||
print "{" descrCpu "}, " vendor" famille" family", modèle"model,code", révision" rev
|
||
}' <<< "$cpuinfo"
|
||
)
|
||
cpu3=$(
|
||
gawk -F ':' '
|
||
/address sizes/ { gsub(/ bits/,"b",$2); sub(/physical/,"physique",$2);
|
||
sub(/virtual/,"virtuel",$2); sub(/^ | $/,"",$2); add=$2 }
|
||
/cache size/ {gsub(/ /,"",$2); gsub(/B/,"o",$2); gsub(/K/,"k",$2); cache=$2}
|
||
/bogomips/ { bogomips=sprintf("%d",$2) }
|
||
END { print add ", bogomips: " bogomips ", cache: " cache }' <<< "$cpuinfo"
|
||
)
|
||
fg_cpu=$( echo -e "$cpu1\n$cpu2\n$cpu3" )
|
||
fg_nb_threads=$( grep -c '^processor' <<< $cpuinfo )
|
||
# arch processeur
|
||
[ "$( grep -cm1 'flags.* lm ' /proc/cpuinfo )" -ge 1 ] && fg_cpu_arch="64bits" || fg_cpu_arch="32bits"
|
||
# fabricant
|
||
fg_vendor=$( grep -m1 '^vendor_id' <<< $cpuinfo )
|
||
fg_vendor=${fg_vendor#*: } # extraction valeur vendor
|
||
fg_vendor=${fg_vendor#*: } # extraction valeur vendor
|
||
fg_vendor=${fg_vendor//AuthenticAMD/AMD} # allègement
|
||
fg_vendor=${fg_vendor//GenuineIntel/Intel} # allègement
|
||
# traitement µarchitecture
|
||
[ "$fg_uarch" ] || figet_cpu_uarch
|
||
}
|
||
|
||
# stockage des flags cpu extraits du kernel, assigna $CPU_FLAGS
|
||
figet_cpu_flags(){ # 24/11/2017
|
||
|
||
CPU_FLAGS="
|
||
# https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/cpufeatures.h
|
||
# 11/2017
|
||
## Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0
|
||
FPU ⟷ Onboard FPU
|
||
VME ⟷ Virtual Mode Extensions
|
||
DE ⟷ Debugging Extensions
|
||
PSE ⟷ Page Size Extensions
|
||
TSC ⟷ Time Stamp Counter
|
||
MSR ⟷ Model-Specific Registers
|
||
PAE ⟷ Physical Address Extensions
|
||
MCE ⟷ Machine Check Exception
|
||
CX8 ⟷ CMPXCHG8 instruction
|
||
APIC ⟷ Onboard APIC
|
||
SEP ⟷ SYSENTER/SYSEXIT
|
||
MTRR ⟷ Memory Type Range Registers
|
||
PGE ⟷ Page Global Enable
|
||
MCA ⟷ Machine Check Architecture
|
||
CMOV ⟷ CMOV instructions (plus FCMOVcc, FCOMI with FPU)
|
||
PAT ⟷ Page Attribute Table
|
||
PSE36 ⟷ 36-bit PSEs
|
||
PN ⟷ Processor serial number
|
||
CLFLUSH ⟷ CLFLUSH instruction
|
||
DTS ⟷ Debug Store
|
||
ACPI ⟷ ACPI via MSR
|
||
MMX ⟷ Multimedia Extensions
|
||
FXSR ⟷ FXSAVE/FXRSTOR, CR4.OSFXSR
|
||
SSE ⟷ sse
|
||
SSE2 ⟷ sse2
|
||
SS ⟷ CPU self snoop
|
||
HT ⟷ Hyper-Threading
|
||
TM ⟷ Automatic clock control
|
||
IA64 ⟷ IA-64 processor
|
||
PBE ⟷ Pending Break Enable
|
||
## AMD-defined CPU features, CPUID level 0x80000001, word 1 Don't duplicate feature flags which are redundant with Intel!
|
||
SYSCALL ⟷ SYSCALL/SYSRET
|
||
MP ⟷ MP Capable.
|
||
NX ⟷ Execute Disable
|
||
MMXEXT ⟷ AMD MMX extensions
|
||
FXSR_OPT ⟷ FXSAVE/FXRSTOR optimizations
|
||
PDPE1GB ⟷ GB pages
|
||
RDTSCP ⟷ RDTSCP
|
||
LM ⟷ Long Mode (x86-64)
|
||
3DNOWEXT ⟷ AMD 3DNow! extensions
|
||
3DNOW ⟷ 3DNow!
|
||
## Transmeta-defined CPU features, CPUID level 0x80860001, word 2
|
||
RECOVERY ⟷ CPU in recovery mode
|
||
LONGRUN ⟷ Longrun power control
|
||
LRTI ⟷ LongRun table interface
|
||
## Other features, Linux-defined mapping, word 3 This range is used for feature bits which conflict or are synthesized
|
||
CXMMX ⟷ Cyrix MMX extensions
|
||
K6_MTRR ⟷ AMD K6 nonstandard MTRRs
|
||
CYRIX_ARR ⟷ Cyrix ARRs (= MTRRs)
|
||
CENTAUR_MCR ⟷ Centaur MCRs (= MTRRs)
|
||
## cpu types for specific tunings:
|
||
K8 ⟷ Opteron, Athlon64
|
||
K7 ⟷ Athlon
|
||
P3 ⟷ P3
|
||
P4 ⟷ P4
|
||
CONSTANT_TSC ⟷ TSC ticks at a constant rate
|
||
UP ⟷ smp kernel running on up
|
||
ART ⟷ Platform has always running timer (ART)
|
||
ARCH_PERFMON ⟷ Intel Architectural PerfMon
|
||
PEBS ⟷ Precise-Event Based Sampling
|
||
BTS ⟷ Branch Trace Store
|
||
SYSCALL32 ⟷ syscall in ia32 userspace
|
||
SYSENTER32 ⟷ sysenter in ia32 userspace
|
||
REP_GOOD ⟷ rep microcode works well
|
||
MFENCE_RDTSC ⟷ Mfence synchronizes RDTSC
|
||
LFENCE_RDTSC ⟷ Lfence synchronizes RDTSC
|
||
ACC_POWERAMD ⟷ Accumulated Power Mechanism
|
||
NOPL ⟷ instructions
|
||
ALWAYS ⟷ Always-present feature
|
||
XTOPOLOGY ⟷ cpu topology enum extensions
|
||
TSC_RELIABLE ⟷ TSC is known to be reliable
|
||
NONSTOP_TSC ⟷ TSC does not stop in C states
|
||
CPUID ⟷ CPU has CPUID instruction itself
|
||
EXTD_APICID ⟷ has extended APICID (8 bits)
|
||
AMD_DCM ⟷ multi-node processor
|
||
APERFMPERF ⟷ APERFMPERF
|
||
NONSTOP_TSC_S3 ⟷ TSC doesn't stop in S3 state
|
||
TSC_KNOWN_FREQ ⟷ TSC has known frequency
|
||
## Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4
|
||
PNI ⟷ SSE-3
|
||
PCLMULQDQ ⟷ PCLMULQDQ instruction
|
||
DTES64 ⟷ 64-bit Debug Store
|
||
MONITOR ⟷ Monitor/Mwait support
|
||
DS_CPL ⟷ CPL Qual. Debug Store
|
||
VMX ⟷ Hardware virtualization
|
||
SMX ⟷ Safer mode
|
||
EST ⟷ Enhanced SpeedStep
|
||
TM2 ⟷ Thermal Monitor 2
|
||
SSSE3 ⟷ Supplemental SSE-3
|
||
CID ⟷ Context ID
|
||
SDBG ⟷ Silicon Debug
|
||
FMA ⟷ Fused multiply-add
|
||
CX16 ⟷ CMPXCHG16B
|
||
XTPR ⟷ Send Task Priority Messages
|
||
PDCM ⟷ Performance Capabilities
|
||
PCID ⟷ Process Context Identifiers
|
||
DCA ⟷ Direct Cache Access
|
||
SSE4_1 ⟷ SSE-4.1
|
||
SSE4_2 ⟷ SSE-4.2
|
||
X2APIC ⟷ x2APIC
|
||
MOVBE ⟷ MOVBE instruction
|
||
POPCNT ⟷ POPCNT instruction
|
||
TSC_DEADLINE_TIMER ⟷ Tsc deadline timer
|
||
AES ⟷ AES instructions
|
||
XSAVE ⟷ XSAVE/XRSTOR/XSETBV/XGETBV
|
||
OSXSAVE ⟷ XSAVE enabled in the OS
|
||
AVX ⟷ Advanced Vector Extensions
|
||
F16C ⟷ 16-bit fp conversions
|
||
RDRAND ⟷ The RDRAND instruction
|
||
HYPERVISOR ⟷ Running on a hypervisor
|
||
## VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5
|
||
RNG ⟷ RNG present (xstore)
|
||
RNG_EN ⟷ RNG enabled
|
||
ACE ⟷ on-CPU crypto (xcrypt)
|
||
ACE_EN ⟷ on-CPU crypto enabled
|
||
ACE2 ⟷ Advanced Cryptography Engine v2
|
||
ACE2_EN ⟷ ACE v2 enabled
|
||
PHE ⟷ PadLock Hash Engine
|
||
PHE_EN ⟷ PHE enabled
|
||
PMM ⟷ PadLock Montgomery Multiplier
|
||
PMM_EN ⟷ PMM enabled
|
||
## More extended AMD flags: CPUID level 0x80000001, ecx, word 6
|
||
LAHF_LM ⟷ LAHF/SAHF in long mode
|
||
CMP_LEGACY ⟷ If yes HyperThreading not valid
|
||
SVM ⟷ Secure virtual machine
|
||
EXTAPIC ⟷ Extended APIC space
|
||
CR8_LEGACY ⟷ CR8 in 32-bit mode
|
||
ABM ⟷ Advanced bit manipulation
|
||
SSE4A ⟷ SSE-4A
|
||
MISALIGNSSE ⟷ Misaligned SSE mode
|
||
3DNOWPREFETCH ⟷ 3DNow prefetch instructions
|
||
OSVWOS ⟷ Visible Workaround
|
||
IBS ⟷ Instruction Based Sampling
|
||
XOP ⟷ extended AVX instructions
|
||
SKINIT ⟷ SKINIT/STGI instructions
|
||
WDT ⟷ Watchdog timer
|
||
LWP ⟷ Light Weight Profiling
|
||
FMA44 ⟷ operands MAC instructions
|
||
TCE ⟷ translation cache extension
|
||
NODEID_MSR ⟷ NodeId MSR
|
||
TBM ⟷ trailing bit manipulations
|
||
TOPOEXT ⟷ topology extensions CPUID leafs
|
||
PERFCTR_CORE ⟷ core performance counter extensions
|
||
PERFCTR_NB ⟷ NB performance counter extensions
|
||
BPEXT ⟷ data breakpoint extension
|
||
PTSC ⟷ performance time-stamp counter
|
||
PERFCTR_LLC ⟷ Last Level Cache performance counter extensions
|
||
MWAITX ⟷ MWAIT extension (MONITORX/MWAITX)
|
||
## Auxiliary flags: Linux defined - For features scattered in various CPUID levels like 0x6, 0xA etc, word 7.
|
||
RING3MWAIT ⟷ Ring 3 MONITOR/MWAIT
|
||
CPUID_FAULT ⟷ Intel CPUID faulting
|
||
CPB ⟷ AMD Core Performance Boost
|
||
EPB ⟷ IA32_ENERGY_PERF_BIAS support
|
||
CAT_L3 ⟷ Cache Allocation Technology L3
|
||
CAT_L2 ⟷ Cache Allocation Technology L2
|
||
CDP_L3 ⟷ Code and Data Prioritization L3
|
||
HW_PSTATE ⟷ AMD HW-PState
|
||
PROC_FEEDBACK ⟷ AMD ProcFeedbackInterface
|
||
SME ⟷ AMD Secure Memory Encryption
|
||
INTEL_PPIN ⟷ Intel Processor Inventory Number
|
||
INTEL_PT ⟷ Intel Processor Trace
|
||
AVX512_4VNNIW ⟷ AVX-512 Neural Network Instructions
|
||
AVX512_4FMAPS ⟷ AVX-512 Multiply Accumulation Single precision
|
||
MBA ⟷ Memory Bandwidth Allocation
|
||
## Virtualization flags: Linux defined, word 8
|
||
TPR_SHADOW ⟷ Intel TPR Shadow
|
||
VNMI ⟷ Intel Virtual NMI
|
||
FLEXPRIORITY ⟷ Intel FlexPriority
|
||
EPT ⟷ Intel Extended Page Table
|
||
VPID ⟷ Intel Virtual Processor ID
|
||
VMMCALL ⟷ Prefer vmmcall to vmcall
|
||
XENPV ⟷ Xen paravirtual guest
|
||
## Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9
|
||
FSGSBASE ⟷ {RD/WR}{FS/GS}BASE instructions
|
||
TSC_ADJUST ⟷ TSC adjustment MSR 0x3b
|
||
BMI1 ⟷ 1st group bit manipulation extensions
|
||
HLE ⟷ Hardware Lock Elision
|
||
AVX2 ⟷ AVX2 instructions
|
||
SMEP ⟷ Supervisor Mode Execution Protection
|
||
BMI2 ⟷ 2nd group bit manipulation extensions
|
||
ERMS ⟷ Enhanced REP MOVSB/STOSB
|
||
INVPCID ⟷ Invalidate Processor Context ID
|
||
RTM ⟷ Restricted Transactional Memory
|
||
CQM ⟷ Cache QoS Monitoring
|
||
MPX ⟷ Memory Protection Extension
|
||
RDT_A ⟷ Resource Director Technology Allocation
|
||
AVX512F ⟷ AVX-512 Foundation
|
||
AVX512DQ ⟷ AVX-512 DQ (Double/Quad granular) Instructions
|
||
RDSEED ⟷ The RDSEED instruction
|
||
ADX ⟷ The ADCX and ADOX instructions
|
||
SMAP ⟷ Supervisor Mode Access Prevention
|
||
AVX512IFMA ⟷ AVX-512 Integer Fused Multiply-Add instructions
|
||
CLFLUSHOPT ⟷ CLFLUSHOPT instruction
|
||
CLWB ⟷ CLWB instruction
|
||
AVX512PF ⟷ AVX-512 Prefetch
|
||
AVX512ER ⟷ AVX-512 Exponential and Reciprocal
|
||
AVX512CD ⟷ AVX-512 Conflict Detection
|
||
SHA_NI ⟷ SHA1/SHA256 Instruction Extensions
|
||
AVX512BW ⟷ AVX-512 BW (Byte/Word granular) Instructions
|
||
AVX512VL ⟷ AVX-512 VL (128/256 Vector Length) Extensions
|
||
#Extended state features, CPUID level 0x0000000d:1 (eax), word 10
|
||
XSAVEOPT ⟷ XSAVEOPT
|
||
XSAVEC ⟷ XSAVEC
|
||
XGETBV1 ⟷ XGETBV with ECX = 1
|
||
XSAVES ⟷ XSAVES/XRSTORS
|
||
## Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11
|
||
CQM_LLC ⟷ LLC QoS if 1
|
||
## Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12
|
||
CQM_OCCUP_LLC ⟷ LLC occupancy monitoring if 1
|
||
CQM_MBM_TOTAL ⟷ LLC Total MBM monitoring
|
||
CQM_MBM_LOCAL ⟷ LLC Local MBM monitoring
|
||
## AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13
|
||
CLZERO ⟷ CLZERO instruction
|
||
IRPERF ⟷ Instructions Retired Count
|
||
## Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14
|
||
DTHERM ⟷ Digital Thermal Sensor
|
||
IDA ⟷ Intel Dynamic Acceleration
|
||
ARAT ⟷ Always Running APIC Timer
|
||
PLN ⟷ Intel Power Limit Notification
|
||
PTS ⟷ Intel Package Thermal Status
|
||
HWP ⟷ Intel Hardware P-states
|
||
HWP_NOTIFY ⟷ HWP Notification
|
||
HWP_ACT_WINDOW ⟷ HWP Activity Window
|
||
HWP_EPP ⟷ HWP Energy Perf. Preference
|
||
HWP_PKG_REQ ⟷ HWP Package Level Request
|
||
## AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15
|
||
NPT ⟷ Nested Page Table support
|
||
LBRV ⟷ LBR Virtualization support
|
||
SVM_LOCK ⟷ SVM locking MSR
|
||
NRIP_SAVE ⟷ SVM next_rip save
|
||
TSC_SCALE ⟷ TSC scaling support
|
||
VMCB_CLEAN ⟷ VMCB clean bits support
|
||
FLUSHBYASID ⟷ flush-by-ASID support
|
||
DECODEASSISTS ⟷ Decode Assists support
|
||
PAUSEFILTER ⟷ filtered pause intercept
|
||
PFTHRESHOLD ⟷ pause filter threshold
|
||
AVIC ⟷ Virtual Interrupt Controller
|
||
V_VMSAVE_VMLOAD ⟷ Virtual VMSAVE VMLOAD
|
||
VGIF ⟷ Virtual GIF
|
||
## Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16
|
||
AVX512VBMI ⟷ AVX512 Vector Bit Manipulation instructions
|
||
PKU ⟷ Protection Keys for Userspace
|
||
OSPKEOS ⟷ Protection Keys Enable
|
||
AVX512_VPOPCNTDQ ⟷ POPCNT for vectors of DW/QW
|
||
LA57 ⟷ 5-level page tables
|
||
RDPID ⟷ RDPIDinstruction
|
||
## AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17
|
||
OVERFLOW_RECOV ⟷ MCA overflow recovery support
|
||
SUCCOR ⟷ Uncorrectable error containment and recovery
|
||
SMCA ⟷ Scalable MCA
|
||
"
|
||
}
|
||
|
||
# assigne $fg_uarch
|
||
figet_cpu_uarch(){ # 24/11/2017
|
||
local var_temp vendor family model
|
||
local defaut_model="modèle non répertorié" defaut_family="famille non répertoriée"
|
||
local defaut_vendor="fabricant non répertorié"
|
||
[ "$fg_cpu" ] || figet_cpu # obtention $fg_vendor
|
||
var_temp=$(grep -m1 '^cpu family' /proc/cpuinfo) # family cpuinfo
|
||
var_temp=${var_temp#*: } # extraction valeur family
|
||
family=$(printf "%.2X" $var_temp) # conversion hexa family
|
||
var_temp=$(grep -m1 '^model' /proc/cpuinfo) # model cpuinfo
|
||
var_temp=${var_temp#*: } # extraction valeur model
|
||
model=$(printf "%.2X" $var_temp) # conversion hexa model
|
||
{
|
||
case ${fg_vendor,,} in
|
||
*intel*)
|
||
case $family in
|
||
04) fg_uarch="Intel 80486, 1000 à 600nm";; # arch_x86
|
||
05)
|
||
case $model in
|
||
01 | 02 | 03 | 07) fg_uarch="Intel P5 (Pentium)";; # arch_x86
|
||
04 | 08) fg_uarch="Intel P5 (Pentium MMX)";; # arch_x86
|
||
09) fg_uarch="Intel Quark";; # arch_x86
|
||
*) fg_uarch="Intel $defaut_model";;
|
||
esac ;;
|
||
0B) fg_uarch="Knights Corner (Xeon Phi)";; # arch_x86?
|
||
0F)
|
||
case $model in
|
||
00 | 01 | 02) fg_uarch="Intel NetBurst (P4)";; # arch_x86?
|
||
03 | 04 | 06) fg_uarch="Intel NetBurst (Nocona Prescott)";; # arch_x86?
|
||
*) fg_uarch="Intel $defaut_model";;
|
||
esac ;;
|
||
06)
|
||
case $model in
|
||
01) fg_uarch="Intel Pentium Pro";; # arch_x86
|
||
03 | 04 | 05) fg_uarch="Intel Prescott (Pentium II) 90nm";; # arch_x86
|
||
06) fg_uarch="Intel Presler (Pentium II) 65nm";; # arch_x86
|
||
07 | 08 | 0A | 0B) fg_uarch="Intel (Pentium III)";; # arch_x86
|
||
09 | 15 | 0D) fg_uarch="Intel Dothan (Pentium M) 90nm";; # arch_x86
|
||
0E) fg_uarch="Intel Core";; # arch_x86
|
||
0F | 16) fg_uarch="Intel Merom (Core2) 65nm";;
|
||
17 | 1D) fg_uarch="Intel Penryn (Core2) 45nm";;
|
||
1A | 1E | 1F | 2E) fg_uarch="Intel Nehalem 45nm";;
|
||
25 | 2C | 2F) fg_uarch="Intel Westmere 32nm";;
|
||
2A | 2D) fg_uarch="Intel Sandy Bridge 32nm";;
|
||
3A | 3E) fg_uarch="Intel Ivy Bridge 22nm";;
|
||
3C | 3F | 45 | 46) fg_uarch="Intel Haswell 22nm";;
|
||
3D | 47 | 4F | 56) fg_uarch="Intel Broadwell 14nm";;
|
||
4E | 55 | 5E) fg_uarch="Intel Skylake 14nm";;
|
||
8E | 9E) fg_uarch="Intel Kaby Lake 14nm";;
|
||
# atom
|
||
1C | 26) fg_uarch="Intel Atom Bonnell 45nm";;
|
||
27 |35 |36) fg_uarch="Intel Atom Saltwell 32nm";;
|
||
37 | 4A | 4D | 5A) fg_uarch="Intel Atom Silvermont 22nm";;
|
||
4C | 5D | 5F) fg_uarch="Intel Atom Airmont 14nm";;
|
||
# Knights-series cores
|
||
57) fg_uarch="Intel knights_landing";;
|
||
85) fg_uarch="Intel knights_mill";;
|
||
*) fg_uarch="Intel $defaut_model";;
|
||
esac ;;
|
||
*) fg_uarch="Intel $defaut_family";;
|
||
esac ;;
|
||
*amd*)
|
||
case $family in
|
||
04) # arch_x86
|
||
case $model in
|
||
03 | 07 | 08 | 09 | 0A) fg_uarch="AMD Am486";; # années 90
|
||
0E | 0F) fg_uarch="AMD Am5x86, 350nm";; # 1995-1999
|
||
*) fg_uarch="AMD ?86 $defaut_model";;
|
||
esac ;;
|
||
05) # arch_x86
|
||
case $model in
|
||
00 | 01 | 02 | 03) fg_uarch="AMD K5 SSA/5 ou 5k86, 350nm";; # 1996
|
||
06 | 07) fg_uarch="AMD K6 350, 250nm";; # 1997-1998
|
||
08) fg_uarch="AMD K6-2, 250nm";; # 1998-1999
|
||
09 | 0D) fg_uarch="AMD K6-3 Sharptooth, 250, 180nm";; # 1999-2000
|
||
*) fg_uarch="AMD K5/K6 $defaut_model";;
|
||
esac ;;
|
||
06) fg_uarch="AMD K7 Athlon, 250, 180, 130nm, (Classic/T-Bird/Palomino/T-Bred/Barton and Thorton";; # arch_x86 1999-2005
|
||
0F) # 2003-?
|
||
case $model in
|
||
0? | 1?) fg_uarch="AMD K8 Hammer (SledgeHammer), 130-65nm";;
|
||
2?) fg_uarch="AMD K8 Hammer (SledgeHammer) (rev.E), 130-65nm";;
|
||
4? | 5? | 6? | 7? | C?) fg_uarch="AMD K8 Hammer (SledgeHammer) (rev.F+), 130-65nm";;
|
||
*) fg_uarch="AMD K8 Hammer (SledgeHammer) $defaut_model";;
|
||
esac ;;
|
||
10) fg_uarch="AMD Barcelona K10, 65, 45, 32nm";; # 2007-2012 Agena, Toliman, Thuban, Deneb, Heka, Callisto, Regor, Propus APU: Llano
|
||
11) fg_uarch="AMD Turion X2 Ultra/Puma mobile, dérivée K8/K10, 65, 45nm";; # mixture of K8/K10 designs with lower power consumption
|
||
12) fg_uarch="AMD Fusion, dérivée K10, 32nm";; # Llano
|
||
15)
|
||
case $model in
|
||
00 | 01) fg_uarch="AMD Bulldozer 1ère génération, 32nm";; # 2011- success to K10,
|
||
02 | 1?) fg_uarch="AMD Piledriver (Enhanced Bulldozer) (Bulldozer 2e génération), 32nm";; # 2012- APU: Trinity, Richland
|
||
3?) fg_uarch="AMD Steamroller (Bulldozer 3e génération), 28nm";; # 2014- APU: Kaveri
|
||
6? | 7?) fg_uarch="AMD Excavator (Bulldozer 4e génération), 28nm";; # 2015- gén. finale APU: Carrizo, Bristol Ridge, Stoney Ridge
|
||
*) fg_uarch="AMD Bulldozer, $defaut_model";;
|
||
esac ;;
|
||
17)
|
||
case $model in
|
||
*) "AMD Zen, 14nm";; # 2017- APU: Raven Ridge
|
||
esac ;;
|
||
# basse consommation
|
||
14) fg_uarch="AMD Bobcat, 40nm";; # 2011- APU: Desna, Ontario, Zacate
|
||
16)
|
||
case $model in
|
||
0?) "AMD Jaguar 28nm";; # 2013- APU: Kabini, Temash
|
||
3?) "AMD Puma ou Puma+ (family 16h 2e génération), 28nm";; # 2014- APU: Beema, Mullins, Puma+ APU: Carrizo-L
|
||
*) fg_uarch="AMD family 16h (Jaguar/Puma) $defaut_model";;
|
||
esac ;;
|
||
*) fg_uarch="AMD $defaut_family";;
|
||
esac ;;
|
||
*arm*) fg_uarch="ARM (avec quelques processeurs VIA) $defaut_vendor";; # à vérifier, info kernel, récente fonctionnalité 2016?
|
||
*centaur*) fg_uarch="Centaur (avec quelques processeurs VIA) $defaut_vendor";;
|
||
*cyrix*) fg_uarch="Cyrix $defaut_vendor";;
|
||
*nexgen*) fg_uarch="NexGen $defaut_vendor";;
|
||
*nsc*) fg_uarch="National Semiconductor $defaut_vendor";;
|
||
*rise*) fg_uarch="Rise $defaut_vendor";;
|
||
*sis*) fg_uarch="SiS $defaut_vendor";;
|
||
*transmeta* | *TMx86*) fg_uarch="Transmeta $defaut_vendor";;
|
||
*umc*) fg_uarch="UMC $defaut_vendor";;
|
||
*via*) fg_uarch="VIA $defaut_vendor";;
|
||
*vortex*) fg_uarch="Vortex $defaut_vendor";;
|
||
*) fg_uarch="$defaut_vendor";;
|
||
esac
|
||
}
|
||
[ "$fg_uarch" ] && fg_uarch+=" {0x$family|0x$model}"
|
||
}
|
||
|
||
# assigne $fg_de, $fg_de_panel
|
||
figet_de(){ #v 30/11/2017 # thanks neofetch
|
||
local de="n/a"
|
||
fg_de="n/a"
|
||
[ "$ENV_DISPLAY" ] && fg_de+=":no Display"
|
||
[ "$ENV_SSH" ] && fg_de+=":ssh"
|
||
[[ "$fg_de" =~ : ]] && return 0 # retourne n/a ...
|
||
##
|
||
de="$XDG_CURRENT_DESKTOP"
|
||
de=${de/X-} # supression de X- (X-Cinnamon)
|
||
if [ -z "$de" ]; then
|
||
de="$DESKTOP_SESSION"
|
||
de=${DESKTOP_SESSION##*/} # suppression plus grande chaine au début jusqu'à /
|
||
de=${DESKTOP_SESSION##*=} # suppression plus grande chaine au début jusqu'à =
|
||
fi
|
||
# fallback to using xprop
|
||
if [[ "$wayland" && "$EUID" -eq 0 && -z "$de" ]]; then
|
||
fg_de="n/a:wayland root"
|
||
return 0
|
||
elif [[ -z "$de" ]]; then
|
||
de=$( xprop -root | gawk 'IGNORECASE = 1;/KDE_SESSION_VERSION|^_MUFFIN/' )
|
||
fi
|
||
# Format strings
|
||
if [[ "${de,,}" =~ kde_session_version ]]; then # test sur minuscules
|
||
de="kde"${de/* = }
|
||
elif [[ "${de,,}" =~ tde_full_session ]]; then
|
||
de="trinity" # fork kde 3.5
|
||
elif [[ "${de,,}" =~ muffin || "${de,,}" =~ cinnamon ]]; then
|
||
de=$( cinnamon --version )
|
||
de=${de:-cinnamon} # si nul, cinnamon
|
||
fi
|
||
fg_de=${de,,} # minuscule
|
||
fg_de=${fg_de^} # caractère 1 en majuscule
|
||
###
|
||
# panel
|
||
fg_de_panel=$( gawk ' BEGIN { IGNORECASE=1 }
|
||
#inclus lxpanel, mate-panel, gnome-panel, xfceX-panel
|
||
/(gnome-shell|kicker|plasma-desktop|plasma-netbook|lxpanel|panel)$/ { print $NF }
|
||
' <<< $( ps -A ) )
|
||
|
||
}
|
||
|
||
# $fg_nb_disk : nb disk fixe & amovible, $fg_disk_table : tableau sommaire, fg_disk_serial
|
||
# $fg_disk_fixe : liste devices block fixes, $fg_disk_amov : liste devices block amovibles
|
||
# $fg_disk_part_fix_tot : espace des partitions fixes montées
|
||
# $fg_disk_ata, $fg_disk_usb, $fg_disk_mmc, $fg_disk_nvme : liste disk ata, usb...
|
||
# $fg_disk_part_fixe_m, $fg_disk_part_amov_m : liste partitions montées, fixes ou amovibles
|
||
# $fg_disk_part_swap : liste partitions swap
|
||
# $fg_disk_part_fixe_nm, $fg_disk_part_amov_nm : liste partitions non montées, fixes ou amovibles
|
||
figet_disk(){ #v2 2/12/2017
|
||
local size type list_id idisk lsblk vendor model rev serial
|
||
unset fg_disk_fixe fg_disk_amov
|
||
# bug printf: caractères accentués diminuent 1 caractère sur arguments suivants, ajouter autant d'espaces
|
||
fg_disk_table="$(printf '%-5s %-8s %-6s %-10s %-18s %-6s' "disk" "taille" "type" "vendeur" "modèle" " rév.")"$'\n'
|
||
fg_disk_serial="$(printf '%-5s %-10s %-18s %-6s %-24s %s' "disk" "vendeur" "modèle " " rév." " n° série")"$'\n'
|
||
for idisk in $(grep -v 'loop' <<< $(ls /sys/block/)); do
|
||
size="$( lsblk -no SIZE -d /dev/$idisk | xargs )" #149,1G
|
||
type="$( sed -n '2p' <<< $(lsblk -no HOTPLUG /dev/$idisk) | xargs )" # 0 \n 0 \n ...
|
||
[ "$type" == "0" ] && type="Fixe" || type="Amov"
|
||
vendor="$( lsblk -no VENDOR /dev/$idisk | xargs )"
|
||
model="$( lsblk -no MODEL /dev/$idisk | xargs )"
|
||
serial="$( lsblk -no SERIAL /dev/$idisk | xargs )"
|
||
if [[ -z "$vendor" || -z "$model" ]]; then # tentative extraction valeur via /dev/disk/by-id/
|
||
vendor="n/a"
|
||
vendor="$(ls -l /dev/disk/by-id/ | gawk ' !/-part/ && !/wwn-/ {print $9,$11}' | xargs )"
|
||
vendor="$(sed -E 's/.*-(.*)_[0-9]+.*$/\1/;s/_/ /g' <<< $vendor)"
|
||
fg_disk_table+="$(printf '%-5s %-8s %-6s %s' "$idisk" "$size" "$type" "$vendor")"$'\n'
|
||
fg_disk_serial+="$(printf '%-5s %s %s' "$idisk" "$vendor" "$serial")"$'\n'
|
||
else
|
||
rev="$( lsblk -no REV /dev/$idisk | xargs )"
|
||
fg_disk_table+="$(printf '%-5s %-8s %-6s %-10s %-18s %-6s' "$idisk" "$size" "$type" "$vendor" "$model" "$rev")"$'\n'
|
||
fg_disk_serial+="$(printf '%-5s %-10s %-18s %-6s %-24s %s' "$idisk" "$vendor" "$model" "$rev" "$serial")"$'\n'
|
||
fi
|
||
# liste disques fixes ou amovibles
|
||
if [ "$(lsblk -no HOTPLUG /dev/$idisk | xargs | cut -d' ' -f2)" == "0" ]; then
|
||
fg_disk_fixe+="$idisk " # "sda sdb ..."
|
||
else
|
||
fg_disk_amov+="$idisk "
|
||
fi
|
||
done
|
||
[ "$fg_disk_table" ] && fg_disk_table=${fg_disk_table::-1} # suppression dernier $'\n'
|
||
[ "$fg_disk_serial" ] && fg_disk_serial=${fg_disk_serial::-1} # suppression dernier $'\n'
|
||
# nb de disques (fixe+amovible), peut servir d'indicateur fonction déja appelée
|
||
fg_nb_disk="$(tr ' ' '\n' <<< "$fg_disk_fixe$fg_disk_amov" | grep -c .)"
|
||
# séquences partitions fixes, montées (m) et non montées (nm)
|
||
lsblk="$(lsblk -no KNAME,MOUNTPOINT $(printf '/dev/%s ' $fg_disk_fixe) 2>/dev/null)"
|
||
fg_disk_part_fixe_m="$(echo "$lsblk" | gawk '/\// {print $1}' | tr '\n' ' ')"
|
||
fg_disk_part_fixe_nm="$(echo "$lsblk" | gawk '!/\// && /[0-9]+/ && !/\[SWAP\]/{print $1}' | tr '\n' ' ')"
|
||
# séquences partitions amovibles, montées (m) et non montées (nm)
|
||
lsblk="$(lsblk -no KNAME,MOUNTPOINT $(printf '/dev/%s ' $fg_disk_amov) 2>/dev/null)"
|
||
fg_disk_part_amov_m="$(echo "$lsblk" | gawk '/\// {print $1}' | tr '\n' ' ')"
|
||
fg_disk_part_amov_nm="$(echo "$lsblk" | gawk '!/\// && /[0-9]+/ && !/\[SWAP\]/{print $1}' | tr '\n' ' ')"
|
||
# partitions swap
|
||
fg_disk_part_swap="$(echo "$(lsblk -no KNAME,MOUNTPOINT)" | gawk '/\[SWAP\]/ {print $1}' | tr '\n' ' ')"
|
||
[ "$fg_disk_fixe" ] || fg_disk_fixe="-"
|
||
[ "$fg_disk_amov" ] || fg_disk_amov="-"
|
||
[ "$fg_disk_part_fixe_m" ] || fg_disk_part_fixe_m="-"
|
||
[ "$fg_disk_part_swap" ] || fg_disk_part_swap="-"
|
||
[ "$fg_disk_part_fixe_nm" ] || fg_disk_part_fixe_nm="-"
|
||
[ "$fg_disk_part_amov_m" ] || fg_disk_part_amov_m="-"
|
||
[ "$fg_disk_part_amov_nm" ] || fg_disk_part_amov_nm="-"
|
||
# total espaces partitions fixes montées
|
||
fg_disk_part_fix_tot="partitions fixes montées (total, utilisé, dispo): "
|
||
fg_disk_part_fix_tot+="$(df -h --total --output=size,used,avail $(printf '/dev/%s ' $fg_disk_part_fixe_m) 2>/dev/null | tail -n-1 | xargs)"
|
||
fg_disk_part_fix_tot="$(sed 's/G/Go/g; s/M/Mo/g; s/K/ko/g' <<< $fg_disk_part_fix_tot)"
|
||
[ "$fg_disk_part_fix_tot" ] || fg_disk_part_fix_tot="n/a"
|
||
# liste des disques par type
|
||
list_id="$(ls -l /dev/disk/by-id/ | gawk '{print $9,$11}')"
|
||
fg_disk_ata="$(sed '/^ata/!d; /part/d' <<< $list_id | gawk -F '/' '{print $NF}' | tr '\n' ' ')"
|
||
fg_disk_usb="$(sed -n '/part/d; /^usb/p' <<< $list_id | gawk -F '/' '{print $NF}' | tr '\n' ' ')"
|
||
# fg_disk_mmc="$(sed '/^mmc/!d; /part/d; /\/mmcblk/!d; s/^.*\(mmcblk..*\)$/\1/' <<< $list_id | tr '\n' ' ')"
|
||
fg_disk_mmc="$(sed '/^mmc/!d; /part/d' <<< $list_id | gawk -F '/' '{print $NF}' | tr '\n' ' ')"
|
||
fg_disk_nvme="$(sed '/^nvme/!d; /part/d' <<< $list_id | gawk -F '/' '{print $NF}' | tr '\n' ' ')"
|
||
[ "$fg_disk_ata" ] || fg_disk_ata="-" && fg_disk_ata="$(tr ' ' '\n' <<< "$fg_disk_ata" | sort | tr '\n' ' ')"
|
||
[ "$fg_disk_usb" ] || fg_disk_usb="-" && fg_disk_usb="$(tr ' ' '\n' <<< "$fg_disk_usb" | sort | tr '\n' ' ')"
|
||
[ "$fg_disk_mmc" ] || fg_disk_mmc="-" && fg_disk_mmc="$(tr ' ' '\n' <<< "$fg_disk_mmc" | sort | tr '\n' ' ')"
|
||
[ "$fg_disk_nvme" ] || fg_disk_nvme="-" && fg_disk_nvme="$(tr ' ' '\n' <<< "$fg_disk_nvme" | sort | tr '\n' ' ')"
|
||
}
|
||
|
||
# assigne $fg_distrib
|
||
figet_distrib(){ #v 23/11/2017
|
||
local prefix version
|
||
# priorité /etc/os-release, version officielle systemd
|
||
[ -e "/etc/os-release" ] && source "/etc/os-release" || source "/usr/lib/os-release"
|
||
if [ "$PRETTY_NAME" ] && [ "${PRETTY_NAME,,}" != "Linux" ]; then
|
||
fg_distrib="${PRETTY_NAME:-${NAME} ${ID}}" # si PRETTY_NAME null, alors tentative sur NAME et ID
|
||
fg_distrib=${fg_distrib//'"'} # suppression "
|
||
fi
|
||
# essai version sur fichier
|
||
version=$(cat /etc/*version 2>/dev/null) # fichier *version?
|
||
[[ $version =~ [0-9.]+ ]] || unset version # qui contient des chiffres
|
||
# essai lsb_release, antique méthode
|
||
[ "$fg_distrib" ] && [[ $(grep -is 'chrome-' /proc/version) || -f "/dev/cros_ec" ]] && fg_distrib="$(lsb_release -sd 2>/dev/null)/xhrome-os"
|
||
[ "$fg_distrib" ] && [ $(grep -is 'microsoft' /proc/version) ] && fg_distrib="$(lsb_release -sd 2>/dev/null)/windows"
|
||
[ "$fg_distrib" ] || fg_distrib=$(lsb_release -sd 2>/dev/null)
|
||
# prefix sur nom fichier éventuels *[_-][version|release]
|
||
[ "$prefix" ] || prefix=$(ls /etc/*_version 2>/dev/null | sed -En 's#/etc/(.*)_version#\1#p')
|
||
[ "$prefix" ] || prefix=$(ls /etc/*-version 2>/dev/null | sed -En 's#/etc/(.*)-version#\1#p')
|
||
[ "$prefix" ] || prefix=$(ls /etc/*-release 2>/dev/null | grep -v 'os-release' | sed -En 's#/etc/(.*)-release#\1#p')
|
||
# spécial complément
|
||
[ "$prefix" == "redstar" ] && prefix="Red Star OS"
|
||
[ "$prefix" ] && prefix=${prefix^} # 1er caractère majuscule
|
||
# final
|
||
if [[ "$fg_distrib" && ! "$fg_distrib" =~ $prefix ]]; then # si fg_distrib et ne contient pas prefix
|
||
fg_distrib="$prefix - $fg_distrib $(xargs <<< $version)"
|
||
elif [ -z "$fg_distrib" ] && [ "$prefix" ]; then # si fg_distrib vide et si prefix
|
||
fg_distrib="$prefix $(xargs <<< $version)"
|
||
else
|
||
fg_distrib="$fg_distrib $(xargs <<< $version)" # utilisation fg_distrib "normal", sans préfixe (compris dans fg_distrib)
|
||
fi
|
||
fg_distrib=${fg_distrib% } # suppression espace final éventuel
|
||
[ "$fg_distrib" ] || fg_distrib="${OS^} (indéterminé)"
|
||
}
|
||
|
||
# display manager, assigne $fg_dsp_mngr (liste) ou 'n/a', $fg_dsp_mngr_actif
|
||
figet_dm(){ #v1 27/11/2017
|
||
local dm_list="cdm entranced gdm3 gdm qingy kdm ldm lightdm lxdm mdm nodm orthos sddm slim wdm xdm"
|
||
local idm ps systemctl x11
|
||
fg_dsp_mngr=""
|
||
ps=$(ps -ef) # plus joli pour cmde manuelle ps=$(ps -auxf)
|
||
ps=${ps,,} # tout en minuscules
|
||
for idm in $dm_list; do
|
||
if grep -iq "bin/$idm$" <<< "$ps"; then
|
||
# if [ "${ps/*"$idm"*/test}" == "test" ]; then # pb: doublon gdm/gdm3 fun & speed? grepless (remplacement $idm et alentours, si idm présent, valeur test)
|
||
fg_dsp_mngr+="${idm^} "
|
||
fg_dsp_mngr_actif="${idm^}"
|
||
elif [[ -e /var/run/$idm".pid" || -e /var/run/$idm".pid" || -e /run/$idm || -e /run/$idm || -d /run/$idm/ || -d /var/run/$idm/ ]]; then
|
||
fg_dsp_mngr+="${idm^} "
|
||
fg_dsp_mngr_actif="${idm^}"
|
||
fi
|
||
done
|
||
fg_dsp_mngr=${fg_dsp_mngr% } # supression espace final
|
||
if [[ -z "$fg_dsp_mngr" && -e "/etc/X11/default-display-manager" ]]; then
|
||
x11=$(cat /etc/X11/default-display-manager)
|
||
fg_dsp_mngr=${x11##*/} # conservation dernier champs ifs '/'
|
||
fi
|
||
if [[ -z "$fg_dsp_mngr" && "${ps/*startx*/test}" == "test" ]]; then
|
||
fg_dsp_mngr="(startx)"
|
||
fg_dsp_mngr_actif="(startx)"
|
||
fi
|
||
fg_dsp_mngr_actif=${fg_dsp_mngr_actif^}
|
||
if [[ -z "$fg_dsp_mngr_actif" && $( type -p systemctl 2>/dev/null ) ]]; then
|
||
fg_dsp_mngr_actif=$(grep 'Main PID' <<< $(systemctl status display-manager))
|
||
fg_dsp_mngr_actif=${fg_dsp_mngr_actif##* } # conservation dernier champs ifs ' '
|
||
fg_dsp_mngr_actif=${fg_dsp_mngr_actif/\(/} # suppression (
|
||
fg_dsp_mngr_actif=${fg_dsp_mngr_actif/\)/} # suppression )
|
||
[ ${fg_dsp_mngr// } ] || fg_dsp_mngr="$fg_dsp_mngr_actif"
|
||
fi
|
||
[ "$fg_dsp_mngr" ] || fg_dsp_mngr="n/a"
|
||
[ "$fg_dsp_mngr_actif" ] || fg_dsp_mngr_actif="n/a"
|
||
}
|
||
|
||
# informations DMI (firmware partie matériel), $1=[head], assigne $fg_dmi
|
||
figet_dmi(){ #v2 01/12/2017
|
||
local product board bios tempo idmi indic1="" indic2=""
|
||
local chassis_type=( # type de chassis selon smbios janvier 2017
|
||
# http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf
|
||
# DSP0134 version: 3.1.1, janvier 2017, $ 7.4.1 System Enclosure or Chassis Types, table 17
|
||
'Other' #01h
|
||
'Unknown' #02h
|
||
'Desktop' #03h
|
||
'Low Profile Desktop' #04h
|
||
'Pizza Box' #05h
|
||
'Mini Tower' #06h
|
||
'Tower' #07h
|
||
'Portable' #08h
|
||
'Laptop' #09h
|
||
'Notebook' #0Ah
|
||
'Hand Held' #0Bh
|
||
'Docking Station' #0Ch
|
||
'All in One' #0Dh
|
||
'Sub Notebook' #0Eh
|
||
'Space-saving' #0Fh
|
||
'Lunch Box' #10h
|
||
'Main Server Chassis' #11h
|
||
'Expansion Chassis' #12h
|
||
'SubChassis' #13h
|
||
'Bus Expansion Chassis' #14h
|
||
'Peripheral Chassis' #15h
|
||
'RAID Chassis' #16h
|
||
'Rack Mount Chassis' #17h
|
||
'Sealed-case PC' #18h
|
||
'Multi-system chassis' #19h
|
||
'Compact PCI' #1Ah
|
||
'Advanced TCA' #1Bh
|
||
'Blade' #1Ch
|
||
'Blade Enclosure' #1Dh
|
||
'Tablet' #1Eh
|
||
'Convertible' #1Fh
|
||
'Detachable' #20h
|
||
)
|
||
# ligne1 $product
|
||
for idmi in sys_vendor product_name product_version chassis_type; do
|
||
tempo=$( cat /sys/class/dmi/id/$idmi 2>/dev/null ) # extraction valeur
|
||
tempo=$( sed 's/x.xx*//; s/To be filled by O\.E\.M\.//g' <<< $tempo | xargs ) # ménage
|
||
if [ "$idmi" == "chassis_type" ]; then
|
||
tempo="( ${chassis_type[ $(( ${tempo##0} - 1 )) ]} )" # valeur tableau après mise en forme index
|
||
fi
|
||
# indic1 pour tester égalité avec $board
|
||
[[ "$idmi" == "sys_vendor" || "$idmi" == "product_name" ]] && indic1+="$tempo "
|
||
product+="$tempo "
|
||
done
|
||
# ligne2 $board (carte mère) éventuellement pas affiché
|
||
for idmi in board_vendor board_name board_version; do
|
||
tempo=$( cat /sys/class/dmi/id/$idmi 2>/dev/null )
|
||
tempo=$( sed 's/x.xx*//; s/To be filled by O\.E\.M\.//g' <<< $tempo | xargs )
|
||
# indic2 pour tester égalité avec $product
|
||
[[ "$idmi" == "board_vendor" || "$idmi" == "board_name" ]] && indic2+="$tempo "
|
||
board+="$tempo "
|
||
done
|
||
# ligne3 $bios
|
||
for idmi in bios_vendor bios_version bios_date; do
|
||
tempo=$( cat /sys/class/dmi/id/$idmi 2>/dev/null )
|
||
tempo=$( sed 's/x.xx*//; s/To be filled by O\.E\.M\.//g' <<< $tempo | xargs )
|
||
bios+="$tempo "
|
||
done
|
||
|
||
if [ "$1" == "head" ]; then
|
||
[ "$product" ] && fg_dmi=$(printf "%-5s : %s " "prod." "$product")$'\n'
|
||
[[ "$board" && "$indic1" != "$indic2" ]] && fg_dmi+=$(printf "%-5s : %s " "board" "$board")$'\n'
|
||
[ "$bios" ] && fg_dmi+=$(printf "%-5s : %s " "bios" "$bios")
|
||
fi
|
||
[ "$product" ] && fg_dmi="$product "$'\n'
|
||
[[ "$board" && "$indic1" != "$indic2" ]] && fg_dmi+="$board "$'\n'
|
||
[ "$bios" ] && fg_dmi+="$bios "
|
||
fg_dmi=${fg_dmi//Inc. }
|
||
fg_dmi=${fg_dmi//INC. }
|
||
fg_dmi=${fg_dmi//Computer }
|
||
fg_dmi=${fg_dmi//COMPUTER }
|
||
}
|
||
|
||
# infos température et fan via acpi, assigne $fg_hw
|
||
figet_hw(){ #v2 31/10/2017
|
||
local name labelF inputF labelT inputT critT hystT maxiT fan temp ihw
|
||
if [ ! -d /sys/class/hwmon/ ]; then
|
||
fg_hw="gestion acpi hwmon non accessible"
|
||
return 1
|
||
fi
|
||
unset fan temp
|
||
for ihw in $(ls /sys/class/hwmon/); do
|
||
[ -e /sys/class/hwmon/$ihw/name ] && name="$(cat /sys/class/hwmon/$ihw/name)" || name="indéfini"
|
||
## TEMPÉRATURE
|
||
if grep -Eq 'temp[0-9]+' <<< $(ls /sys/class/hwmon/$ihw/) ; then
|
||
# extraction label
|
||
# labelT=$(printf "%s/" "$(cat /sys/class/hwmon/$ihw/temp*_label 2>/dev/null)" | sed 's/ //g' | tr '\n' ' ')
|
||
labelT=$(printf "%s/" "$(cat /sys/class/hwmon/$ihw/temp*_label 2>/dev/null)" | tr ' ' '.' | tr '\n' ' ')
|
||
# extraction températures
|
||
inputT=$(gawk '$0!="" && $0!=0 {printf "%.1f/", $1/1000}' <<< $(cat /sys/class/hwmon/$ihw/temp*_input 2>/dev/null))
|
||
critT=$(gawk '$0!="" && $0!=0 {printf "%.1f/", $1/1000}' <<< $(cat /sys/class/hwmon/$ihw/temp*_crit 2>/dev/null))
|
||
hystT=$(gawk '$0!="" && $0!=0 {printf "%.1f/", $1/1000}' <<< $(cat /sys/class/hwmon/$ihw/temp*_crit_hyst 2>/dev/null))
|
||
maxiT=$(gawk '$0!="" && $0!=0 {printf "%.1f/", $1/1000}' <<< $(cat /sys/class/hwmon/$ihw/temp*_max 2>/dev/null))
|
||
# suppression doublons
|
||
critT=$(echo $critT | tr '/' '\n' | sort --unique | tr '\n' '/')
|
||
hystT=$(echo $hystT | tr '/' '\n' | sort --unique | tr '\n' '/')
|
||
maxiT=$(echo $maxiT | tr '/' '\n' | sort --unique | tr '\n' '/')
|
||
# suppression premier /
|
||
critT=${critT#/} #[ ${critT:0:1} == "/" ] && critT=${critT:1}
|
||
hystT=${hystT#/} # suppression / en début de variable
|
||
maxiT=${maxiT#/}
|
||
# suppression dernier caractère (/) fin (nécessaire si multi-valeurs)
|
||
[ "$inputT" ] && inputT=${inputT::-1}
|
||
[ "$labelT" ] && labelT=${labelT::-1}
|
||
[ "$critT" ] && critT=${critT::-1}
|
||
[ "$hystT" ] && hystT=${hystT::-1}
|
||
[ "$maxiT" ] && maxiT=${maxiT::-1}
|
||
# formation affichage
|
||
if [ "$inputT" ]; then
|
||
temp+="$(printf "%-8s %s°C %s " "$name" "$inputT" "$labelT")"
|
||
[ "$critT" ] && temp+="(crit: $critT""°C) "
|
||
[ "$hystT" ] && temp+="(hyst: $hystT""°C) "
|
||
[ "$maxiT" ] && temp+="(maxi: $maxiT""°C) "
|
||
[ "$temp" ] && temp+=$'\n'
|
||
fi
|
||
fi
|
||
## FAN
|
||
if grep -Eq 'fan[0-9]+' <<< $(ls /sys/class/hwmon/$ihw/) ; then
|
||
# extraction label
|
||
labelF=$(printf "%s/" $(cat /sys/class/hwmon/$ihw/fan*_label 2>/dev/null))
|
||
# extraction vitesse fan, \047=' pour insérer séparateur de milliers
|
||
inputF=$(gawk '$0!="" && $0!=0 {printf "%\047d/", $1}' <<< $(cat /sys/class/hwmon/$ihw/fan*_input 2>/dev/null))
|
||
# suppression dernier caractère (/) fin (nécessaire si multi-valeurs)
|
||
[ "$labelF" ] && labelF=${labelF::-1}
|
||
[ "$inputF" ] && inputF=${inputF::-1}
|
||
# formation affichage
|
||
if [ "$inputF" ]; then
|
||
fan+="$(printf "%-8s %st/mn %s" "$name" "$inputF" "$labelF")"$'\n'
|
||
fi
|
||
fi
|
||
done
|
||
fg_hw="$temp$fan"
|
||
[ "$fg_hw" ] && fg_hw=${fg_hw::-1}
|
||
}
|
||
|
||
# assigne $fg_ip, $fg_ip_tp, $fg_gws, $fg_gws_tp, $fg_ifn_prior, $fg_ifn, $fg_mac, fg_mac_tp
|
||
figet_ip(){ # 27/11/2017
|
||
local ifn
|
||
[ $( f__which ip ) ] || return 1
|
||
fg_ip="$(sed '/[[:digit:]]:[[:blank:]]lo.*inet/d; /inet6.*scope/d' <<< $(ip -o a) | gawk '{print " ",$4,"(",$2,")"}')"
|
||
fg_ip_tp="$(sed -E 's/(^.*wl.*)/\1 (wifi)/;s/(^.*en.*|^.*eth.*)/\1 (ethernet)/' <<< $fg_ip)"
|
||
fg_gws="$(LC_ALL=C ip -4 route | gawk '/default via/ {print " ",$3,"(",$5,")"}')"
|
||
fg_gws+="$(LC_ALL=C ip -6 route | gawk '/default via/ {print " ",$3,"(",$5,")"}')"
|
||
fg_gws_tp="$(sed -E 's/(^.*wl.*)/\1 (wifi)/;s/(^.*en.*|^.*eth.*)/\1 (ethernet)/' <<< $fg_gws)"
|
||
fg_ifn_prior="$(ip route get 255.255.255.255 | sed -nr 's/.*src ([0-9.]+).*/\1/p')"
|
||
for ifn in $(ls /sys/class/net/) ; do
|
||
[ "$ifn" != "lo" ] && fg_ifn+=" $ifn"$'\n'
|
||
[ "$ifn" != "lo" ] && fg_mac+=" $ifn: $(cat /sys/class/net/$ifn/address)"$'\n'
|
||
done
|
||
# fg_ifn="$(sed '/^[[:blank:]]*$/d' <<< $fg_ifn)" # suppression lignes vides
|
||
# fg_mac="$(sed '/^[[:blank:]]*$/d' <<< $fg_mac)" # suppression lignes vides
|
||
# voir cat /sys/class/net/wlp1s0/uevent
|
||
fg_mac_tp="$(sed -E 's/(^.*wl.*)/\1 (wifi)/;s/(^.*en.*|^.*eth.*)/\1 (ethernet)/' <<< $fg_mac)"
|
||
fg_ifn=${fg_ifn%[[:cntrl:]]} # suppression dernier $'\n'
|
||
fg_mac_tp=${fg_mac_tp%[[:cntrl:]]} # suppression dernier $'\n'
|
||
}
|
||
|
||
# $1=4|6, assigne $fg_public
|
||
figet_ip_pub(){ # 20/11/2017
|
||
local dig_test ip_test iip
|
||
list_ip4(){
|
||
ip_test+=" http://whatismyip.akamai.com"
|
||
ip_test+=" http://ipof.in/txt"
|
||
ip_test+=" http://eth0.me"
|
||
ip_test+=" http://ipecho.net/plain"
|
||
ip_test+=" http://alma.ch/myip.cgi"
|
||
ip_test+=" http://checkip.amazonaws.com"
|
||
ip_test+=" http://eth0.me"
|
||
ip_test+=" http://ipecho.net/plain"
|
||
ip_test+=" api.infoip.io/ip" # http & https
|
||
ip_test+=" api.ipify.org" # http & https
|
||
ip_test+=" ipinfo.io/ip" # http & https
|
||
}
|
||
list_ip6(){
|
||
ip_test+=" http://ipv6.whatismyip.akamai.com"
|
||
ip_test+=" http://bot.whatismyipaddress.com"
|
||
ip_test+=" ip.tyk.nu" # http & https
|
||
ip_test+=" l2.io/ip" # http & https
|
||
ip_test+=" ident.me" # http & https
|
||
ip_test+=" icanhazip.com" # http & https
|
||
ip_test+=" wgetip.com" # http & https
|
||
ip_test+=" https://canhazip.com"
|
||
ip_test+=" https://tnx.nl/ip"
|
||
}
|
||
list_ip4_dig(){
|
||
dig_test+=" whoami.akamai.net/@ns1-1.akamaitech.net"
|
||
dig_test+=" myip.opendns.com/@resolver1.opendns.com"
|
||
dig_test+=" myip.opendns.com/@resolver2.opendns.com"
|
||
dig_test+=" myip.opendns.com/@resolver3.opendns.com"
|
||
dig_test+=" myip.opendns.com/@resolver4.opendns.com"
|
||
}
|
||
list_ip6_dig(){
|
||
dig_test+=" -6/myip.opendns.com/aaaa/@resolver1.ipv6-sandbox.opendns.com"
|
||
dig_test+=" -6/myip.opendns.com/aaaa/@resolver2.ipv6-sandbox.opendns.com"
|
||
}
|
||
|
||
unset fg_public
|
||
if [ "$1" == "4" ]; then
|
||
ping -4 -c1 google.com &>/dev/null || ping -4 -c1 free.fr &>/dev/null || return 1 # test connectivité
|
||
list_ip4_dig
|
||
list_ip4
|
||
ip_telnet=4.ifcfg.me
|
||
elif [ "$1" == "6" ]; then
|
||
ping -6 -c1 google.com &>/dev/null || ping -6 -c1 free.fr &>/dev/null || return 1 # test connectivité
|
||
list_ip6_dig
|
||
list_ip6
|
||
ip_telnet=6.ifcfg.me
|
||
fi
|
||
|
||
if [ $( f__which dig ) ] && [ -z "$fg_public" ]; then
|
||
for iip in $dig_test ; do
|
||
fg_public="$(dig +short $(sed 's;/; ;g' <<< $iip))"
|
||
[ "$fg_public" ] && break
|
||
done
|
||
fi
|
||
|
||
if [ $( f__which wget ) ] && [ -z "$fg_public" ]; then
|
||
cmd="wget --quiet --timeout=5 -O - "
|
||
for iip in $ip_test ; do
|
||
fg_public="$($cmd $iip)"
|
||
[ "$fg_public" ] && break
|
||
done
|
||
fi
|
||
|
||
if [ $( f__which curl ) ] && [ -z "$fg_public" ]; then
|
||
cmd="curl --silent --location --retry 0 --max-time 5" #--location pour aider redirections
|
||
for iip in $ip_test ; do
|
||
fg_public="$($cmd $iip)"
|
||
[ "$fg_public" ] && break
|
||
done
|
||
fi
|
||
|
||
if [ $( f__which telnet ) ] && [ -z "$fg_public" ]; then
|
||
fg_public="$(telnet $ip_telnet 23 2>/dev/null | grep $1 | cut -d ' ' -f 4)"
|
||
fi
|
||
|
||
if [ $( f__which nc ) ] && [ -z "$fg_public" ] && [ "$1" != "IPv6" ]; then
|
||
fg_public="$(nc $ip_telnet 23 2>/dev/null | grep $1 | cut -d ' ' -f 4)"
|
||
fi
|
||
|
||
if [ -z "$fg_public" ]; then
|
||
f__error "il manque une des commandes suivantes:\n" \
|
||
"dig / wget / curl / telnet / nc \n" \
|
||
"ou les ip de test sont devenues défaillantes\n" \
|
||
"réessayer après avoir installé dig (dnsutils) et wget\n" \
|
||
"si l'erreur persiste, merci de prévenir $projet, $contact"
|
||
fi
|
||
}
|
||
|
||
# $1=audio|video|net, $2 objet raw|name, $3=[graph] (optirun, DRI)
|
||
figet_lspci(){ # 30/11/2017
|
||
local motif slots lspci display='' prefixCmd
|
||
|
||
if [ "$1" = "audio" ]; then
|
||
motif="Audio device|Audio controller|Multimedia audio controller"
|
||
elif [ "$1" = "video" ]; then
|
||
motif="VGA .* controller|Display controller|3D controller|Graphic|multimedia"
|
||
elif [ "$1" = "net" ]; then
|
||
motif="Ethernet controller|Network controller"
|
||
fi
|
||
# uniquement les devices
|
||
if [ "$2" == "name" ]; then
|
||
while read field1 lspci; do
|
||
lspci=${lspci#*: } # suppression début, jusqu"à': '
|
||
lspci=${lspci% (rev*} # suppression à la fin, '(rev..'
|
||
lspci=${lspci/System Controller Hub } # suppression 'System Controller Hub '
|
||
lspci=${lspci/Advanced Micro Devices, Inc. } # suppression 'Advanced Micro Devices, Inc. '
|
||
lspci=${lspci/Semiconductor Co., Ltd. } # suppression 'Semiconductor Co., Ltd. '
|
||
lspci=${lspci/Corporation } # suppression 'Corporation '
|
||
lspci=${lspci/Limited } # suppression 'Limited '
|
||
lspci=${lspci/Inc. } # suppression 'Inc. '
|
||
lspci=${lspci/Co. } # suppression 'Co. '
|
||
lspci=${lspci/Ltd. } # suppression 'Ltd. '
|
||
lspci=${lspci// } # suppression ' '
|
||
lspci=${lspci/Series Family /Series }
|
||
lspci=${lspci/Series Chipset Family /Series }
|
||
lspci=${lspci/High Definition /HD }
|
||
display+="$lspci"$'\n'
|
||
done <<< $( lspci | grep -Ei "$motif" )
|
||
|
||
# lspci détaillé
|
||
elif [ "$2" == "raw" ]; then
|
||
slots=$( lspci | grep -Ei "$motif" | cut -d" " -f1 )
|
||
if ! lspci -nnv &>/dev/null ; then # commande/option indisponible
|
||
display="lspci -nnv -s <device> non disponible"
|
||
else
|
||
for lspci in $slots; do
|
||
if [[ "$3" == "graph" && "$( f__which optirun )" ]]; then
|
||
lspci=$( optirun lspci -nnv -s $lspci )
|
||
elif [ "$3" == "graph" ]; then
|
||
lspci=$( DRI_PRIME=1 lspci -nnv -s $lspci )
|
||
else
|
||
lspci=$( lspci -nnv -s $lspci ) # normalement inutile, le contexte DRI_PRIME pourrait marcher partout
|
||
fi
|
||
lspci=${lspci/(prog-if*])} # suppression (prog-if...])
|
||
lspci=${lspci/Capabilities: <access denied>[[:cntrl:]][[:blank:]]} # suppression Capabilities: <access denied> (user)
|
||
display+="$lspci"$'\n\n' # double \n pour espace entre card
|
||
done
|
||
fi
|
||
fi
|
||
|
||
display=${display%[[:cntrl:]]} # suppression \n final
|
||
echo -en "$display\n"
|
||
}
|
||
|
||
# $1=mem|swap [total|notitle|nocoltitle], assigne $fg_mem ($2=debug all cols + free)
|
||
# indépendant de procps, affichage plus clair que free, mais résultats identiques
|
||
figet_mem(){ # 27/11/2017
|
||
local freeDebug MemTotal MemFree MemAvailable Buffers Cached SReclaimable Shmem MemUsed
|
||
local SwapTotal SwapFree SwapCached col a b
|
||
[ "$2" == "debug" ] && freeDebug="$(free -hw | sed '3d')"
|
||
IFS=':'
|
||
while read a b; do
|
||
[ "$a" == "MemTotal" ] && MemTotal="${b/kB}" #echo "$a $((${b/kB}/1024))" ! partie entière !
|
||
[ "$a" == "MemAvailable" ] && MemAvailable="${b/kB}"
|
||
[ "$a" == "MemFree" ] && MemFree="${b/kB}"
|
||
[ "$a" == "Buffers" ] && Buffers="${b/kB}"
|
||
[ "$a" == "Cached" ] && Cached="${b/kB}"
|
||
[ "$a" == "SReclaimable" ] && SReclaimable="${b/kB}"
|
||
[[ "$a" =~ Shmem$|MemShared$ ]] && Shmem="${b/kB}" # = free shared
|
||
[ "$a" == "SwapTotal" ] && SwapTotal="${b/kB}"
|
||
[ "$a" == "SwapFree" ] && SwapFree="${b/kB}"
|
||
[ "$a" == "SwapCached" ] && SwapCached="${b/kB}"
|
||
done <<< $(< /proc/meminfo)
|
||
IFS="$IFS_INI"
|
||
MemUsed=$(( $MemTotal-($MemFree+$Buffers+$Cached+$SReclaimable) ))
|
||
SwapUsed=$(( $SwapTotal-$SwapFree ))
|
||
totalTotal=$(( $MemTotal+$SwapTotal ))
|
||
totalUsed=$(( $MemUsed+$SwapUsed ))
|
||
totalAvailable=$(( $MemAvailable+$SwapFree ))
|
||
MemTotal=$( printf '%10s' $(f__unit_human $MemTotal) )
|
||
MemUsed=$( printf '%10s' $(f__unit_human $MemUsed) )
|
||
MemAvailable=$( printf '%10s' $(f__unit_human $MemAvailable) )
|
||
MemFree=$( printf '%10s' $(f__unit_human $MemFree) )
|
||
Buffers=$( printf '%10s' $(f__unit_human $Buffers) )
|
||
Cached=$(( $Cached+$SReclaimable ))
|
||
Cached=$( printf '%10s' $(f__unit_human $Cached) )
|
||
Shmem=$( printf '%10s' $(f__unit_human $Shmem) )
|
||
SwapTotal=$( printf '%10s' $(f__unit_human $SwapTotal) )
|
||
SwapFree=$( printf '%10s' $(f__unit_human $SwapFree) )
|
||
SwapUsed=$( printf '%10s' $(f__unit_human $SwapUsed) )
|
||
SwapCached=$( printf '%10s' $(f__unit_human $SwapCached) )
|
||
totalTotal=$( printf '%10s' $(f__unit_human $totalTotal) )
|
||
totalUsed=$( printf '%10s' $(f__unit_human $totalUsed) )
|
||
totalAvailable=$( printf '%10s' $(f__unit_human $totalAvailable) )
|
||
unset fg_mem
|
||
if [[ ! "$*" =~ notitle ]]; then
|
||
[[ "$*" =~ nocoltitle ]] || col="mémoire"
|
||
fg_mem="$col totale utilisée disponible"$'\n'
|
||
fi
|
||
if [[ "$*" =~ mem ]]; then
|
||
[[ "$*" =~ nocoltitle ]] || col="vive:"
|
||
fg_mem+="$col$MemTotal$MemUsed$MemAvailable"$'\n'
|
||
fi
|
||
if [[ "$*" =~ swap ]]; then
|
||
[[ "$*" =~ nocoltitle ]] || col="swap:"
|
||
fg_mem+="$col$SwapTotal$SwapUsed$SwapFree"$'\n'
|
||
fi
|
||
if [[ "$*" =~ total ]]; then
|
||
[[ "$*" =~ nocoltitle ]] || col="tot.:"
|
||
fg_mem+="$col$totalTotal$totalUsed$totalAvailable"$'\n'
|
||
fi
|
||
if [ "$2" == "debug" ]; then
|
||
local espace=$(printf '% 6s')
|
||
fg_mem="$espace""mém.: totale utilisée libre shared buffers cache disponible"$'\n'
|
||
fg_mem+="$espace""vive:$MemTotal$MemUsed$MemFree$Shmem$Buffers$Cached$MemAvailable"$'\n'
|
||
[ "$fg_mem" ] && fg_mem=${fg_mem::-1} # suppression dernier $'\n'
|
||
echo "$fg_mem"
|
||
echo "$freeDebug"
|
||
fi
|
||
[ "$fg_mem" ] && fg_mem=${fg_mem::-1} # suppression dernier $'\n'
|
||
}
|
||
|
||
# $1=gpu|video|ethernet|wireless|bluetooth [$2=list] séparateur espace si list
|
||
# assigne $fg_modules, $fg_modMotif, fg_modKernel
|
||
# affiche les modules chargés par type
|
||
figet_modules(){ # 30/11/2017
|
||
local modules dir separator
|
||
[ "$1" ] || return 1
|
||
# répertoire à scruter
|
||
dir="/lib/modules/$(uname -r)/kernel/drivers"
|
||
if [ "$1" == "gpu" ]; then
|
||
dir="$dir/gpu/drm"
|
||
elif [ "$1" == "ethernet" ]; then
|
||
dir="$dir/net/ethernet"
|
||
elif [ "$1" == "wireless" ]; then
|
||
dir="$dir/net/wireless"
|
||
else
|
||
dir="$dir/$1"
|
||
fi
|
||
# recherche modules/formation motif ou liste
|
||
[ "$2" == list ] && separator=" " || separator="|" # séparateur | par défaut
|
||
modules=$( ls -1R "$dir/"* | gawk -v separator="$separator" '
|
||
/\.ko/ {
|
||
gsub(/^\/.*:$/,"") # supp ligne répertoire
|
||
gsub(/\/.*\//,"") # supp /../
|
||
gsub(/\.ko/,"") # supp extension .ko
|
||
printf "%s%s",$0,separator }' ) # séparateur espace ou |
|
||
modules=${modules%$separator} # suppression dernier séparateur
|
||
modules=$( echo $modules | tr "$separator" '\n' | sort | tr '\n' "$separator" )
|
||
modules=${modules%$separator} # suppression dernier séparateur
|
||
# affichage si list éventuel
|
||
[ "$2" == list ] && echo -n $modules
|
||
[ "$2" == list ] && return 0
|
||
# recherche modules chargés
|
||
fg_modules="$( lsmod | grep -Ew "$modules" )"
|
||
[ "$fg_modules" ] && fg_modMotif="$modules" || unset fg_modMotif
|
||
fg_modKernel=$( gawk '{ print $1; exit }' <<< $fg_modules )
|
||
}
|
||
|
||
# assigne $fg_nb_screen, $fg_resolution. return fg_resolution=n/a[ (ssh)] & fg_nb_screen=n/a ou valeurs
|
||
figet_screen(){ #v2 25/11/2017
|
||
fg_nb_screen="n/a"
|
||
fg_resolution="n/a"
|
||
[ "$ENV_DISPLAY" ] && fg_resolution+=":no Display"
|
||
[ "$ENV_SSH" ] && fg_resolution+=":ssh"
|
||
[ $( f__which xrandr ) ] || fg_resolution+=":xrandr absent"
|
||
[ $( f__which xdpyinfo ) ] || fg_resolution+=":xdpyinfo absent"
|
||
[[ "$wayland" && "$EUID" -eq 0 ]] && fg_resolution+=":wayland root"
|
||
[[ "$fg_resolution" =~ : ]] && return 0 # retourne n/a ... toutes les causes dans $fg_resolution
|
||
##
|
||
# xrandr & et xdpyinfo ne retourne pas de nombre écrans correct (multiplex? hybrid?)
|
||
fg_resolution=$( gawk '/[0-9]\*/ {gsub(/\*\+/,"",$2); printf "%s pixels (%dHz), ", $1, $2}' <<< $( xrandr --query ) )
|
||
fg_resolution=$( gawk '/dimensions/ { print $2, $3 ", " }' <<< $(xdpyinfo) )
|
||
fg_resolution="${fg_resolution%,*}" # suppression ',*'
|
||
[ "$(xargs <<< $fg_resolution)" ] || fg_resolution="n/a"
|
||
[[ "$fg_resolution" =~ n/a ]] || fg_nb_screen=$( grep -o 'pixels' <<< $fg_resolution | grep -c . )
|
||
}
|
||
|
||
# assigne $fg_shell, $fg_shells
|
||
figet_shell(){ #v2 25/11/2017 # thanks neofetch
|
||
local shell ish
|
||
# shell en cours altern: fg_shell="$( ps -p $PPID -o comm= 2>/dev/null )"
|
||
fg_shell=${SHELL##*/} # suppression jusqu'au dernier /, pas de chemin
|
||
fg_shell=${fg_shell,,}
|
||
case ${shell:=$fg_shell} in # shell nul, donc assigné avec $fg_shell
|
||
bash )
|
||
shell=${BASH_VERSION%-*} # BASH_VERSION: 4.4.12(1)-release, suppression -* final
|
||
;;
|
||
mksh | ksh )
|
||
shell=" "$( "$SHELL" -c 'printf "%s" "$KSH_VERSION"' )
|
||
shell=${shell/ * KSH} # suppression ' * KSH'
|
||
shell=${shell/version} # suppression 'version'
|
||
;;
|
||
* )
|
||
shell=" "$( $SHELL --version 2>/dev/null )
|
||
;;
|
||
esac
|
||
shell=${shell/$fg_shell} # suppression ' nomDuShell'
|
||
shell=${shell/, version}
|
||
shell=${shell/xonsh\//xonsh }
|
||
shell=${shell/options*}
|
||
shell=${shell/\(*\)}
|
||
shell=${shell/ / } # suppression espace double
|
||
fg_shell="${fg_shell^} $shell"
|
||
# shells installés détectés
|
||
if [ -e "/etc/shells" ]; then # by-pass sinon soucis sous fedora et openSuse?
|
||
for ish in $( f_grep_file "/etc/shells" "notitre" ); do # élimine lignes vides et commentées
|
||
fg_shells+=${ish##*/}" " # conservation dernier "champs", ifs '/'
|
||
done
|
||
fg_shells=${fg_shells% } # suppression espace de fin
|
||
fg_shells=$(tr ' ' '\n' <<< $fg_shells | sort -u | tr '\n' ' ') # tri et suppression doublons
|
||
else
|
||
fg_shells="n/a"
|
||
fi
|
||
}
|
||
|
||
# debian indépendant, assigne $fg_ucode (commentaire), $ucode (paquet deb) & return O|1 (1 si pas d'installation)
|
||
figet_ucode(){ # 29/11/2017
|
||
local flagRep xfile xfileTest=""
|
||
# recherche flags cpu rep_good (besoin réel?)
|
||
[ "$( grep -cm1 'flags.*rep_good ' /proc/cpuinfo )" -ge 1 ] && flagRep="rep_good ⟷ rep microcode works well"
|
||
# test possible installation
|
||
[ "$fg_cpu" ] || figet_cpu
|
||
[ "${fg_vendor,,}" == "amd" ] && ucode="amd64-microcode" # si $ucode, µmicorcode possible (amd|intel)
|
||
[ "${fg_vendor,,}" == "intel" ] && ucode="intel-microcode"
|
||
# version debian, à supprimer à terme après essai sur autre distrib
|
||
# if [ "$ENV_DEBIAN" ]; then # debian ?
|
||
# f__requis "$ucode" "debOnly"
|
||
# [ "$debOnlyAbsent" == "$ucode" ] && return 1 || return 0
|
||
# fi
|
||
# test emplacements possibles
|
||
amd64=(
|
||
/etc/default/amd64-microcode
|
||
/etc/modprobe.d/amd64-microcode-blacklist.conf
|
||
/lib/firmware/amd-ucode/microcode_amd.bin
|
||
)
|
||
intel=(
|
||
/etc/kernel/preinst.d/intel-microcode
|
||
/etc/modprobe.d/intel-microcode-blacklist.conf
|
||
/lib/firmware/intel-ucode/
|
||
#$( which iucode_tool 2>/dev/null )
|
||
)
|
||
[[ "${fg_vendor,,}" == "amd" ]] && toScrut=( "${amd64[@]}" ) # array à utiliser selon fabricant
|
||
[ "${fg_vendor,,}" == "intel" ] && toScrut=( "${intel[@]}" )
|
||
for xfile in "${toScrut[@]}"; do
|
||
[ -e "$xfile" ] && xfileTest+="y" # un emplacement, un marqueur
|
||
done
|
||
if [[ ${#xfileTest} -eq 0 && "$ucode" ]]; then # non installé, possible ($ucode)
|
||
fg_ucode="pas de microcode installé bien que existant"
|
||
[ "$flagRep" ] && fg_ucode+=", flag Cpu: REP_GOOD"
|
||
return 1
|
||
elif [[ ${#xfileTest} -eq 0 && -z "$ucode" ]]; then # non installé, non possible
|
||
[ "$flagRep" ] && fg_ucode="pas de microcode existant, mais flag Cpu: REP_GOOD ?!" # pas de commentaire sauf si flag
|
||
return 0
|
||
elif [[ ${#xfileTest} -gt 0 && "$ucode" ]]; then # installé, possible
|
||
fg_ucode="microcode installé"
|
||
[ "$flagRep" ] && fg_ucode+=", flag Cpu: REP_GOOD" || fg_ucode+=", pas de flag Cpu REP_GOOD"
|
||
return 0
|
||
elif [[ ${#xfileTest} -gt 0 && -z "$ucode" ]]; then
|
||
fg_ucode="microcode: détection défaillante" #installé, non possible ?!
|
||
return 0
|
||
fi
|
||
}
|
||
|
||
# assigne $fg_wm (compositor non publique, pas fiabilisé)
|
||
figet_wm(){ #v 2/12/2017 base départ neofetch
|
||
local id wm_brut compositor
|
||
|
||
fg_wm="n/a"
|
||
[ $( f__which xprop ) ] || fg_wm+=":xprop absent" # ! pas de xprop, pas de wm?!
|
||
[ "$ENV_DISPLAY" ] && fg_wm+=":no Display"
|
||
[ "$ENV_SSH" ] && fg_wm+=":ssh"
|
||
[[ "$wayland" && "$EUID" -eq 0 ]] && fg_wm+=":wayland root"
|
||
[[ "$fg_wm" =~ : ]] && return 0 # retourne n/a ...
|
||
##
|
||
# WM
|
||
id=$( xprop -root -notype _NET_SUPPORTING_WM_CHECK ) # = xprop -root | grep _NET_SUPPORTING_WM_CHECK
|
||
id=${id##* } # suppression plus grande chaîne au début jusqu"à ' '
|
||
# wm_brut=$( xprop -id "$id" )
|
||
wm_brut=$( xprop -id "$id" -notype -len 100 -f _NET_WM_NAME 8t ) # xprop -id "$id" -notype _NET_WM_NAME
|
||
[ "$debug" ] && echo -e "\n$( xprop -id "$id" )\n"
|
||
wm_brut=${wm_brut,,} # MINUSCULES
|
||
fg_wm=${wm_brut/*_net_wm_name = } # suppression jusqu'à 'name = '
|
||
fg_wm=${fg_wm/\"} # suppression premier"
|
||
fg_wm=${fg_wm/\"*} # suppression 2e " avec éventuels caractères suivants
|
||
# Window Maker does not set _NET_WM_NAME
|
||
[[ "$fg_wm" =~ "windowmaker" ]] && fg_wm="wmaker"
|
||
# Fallback for Wayland wms (sway)
|
||
[[ "$fg_wm" == "xwlc" ]] && fg_wm=$( ps -e | grep -m1 -Eo 'sway|orbment|velox|orbital' )
|
||
fg_wm=${fg_wm^} # caractère 1 en majuscule
|
||
# Compositor, dev en cours, essai version
|
||
if [[ "$wm_brut" =~ marco_version ]]; then # Mate, ok
|
||
compositor=${wm_brut/*_marco_version = } # suppression jusqu'à ...
|
||
compositor=${compositor/\"} # suppression premier"
|
||
compositor=${compositor/\"*} # suppression 2e " avec éventuels caractères suivants
|
||
compositor="Marco v$compositor"
|
||
fg_wm=${fg_wm/ (marco)} # suppression (marco) dans wm
|
||
fi
|
||
if [[ "$wm_brut" =~ mutter_version ]]; then
|
||
compositor=${wm_brut/*_mutter_version = } # suppression jusqu'à ...
|
||
compositor=${compositor/\"} # suppression premier"
|
||
compositor=${compositor/\"*} # suppression 2e " avec éventuels caractères suivants
|
||
compositor="Mutter v$compositor"
|
||
fi
|
||
if [[ "$wm_brut" =~ muffin_version ]]; then # cinnamon, ok
|
||
compositor=${wm_brut/*muffin_version = } # suppression jusqu'à ...
|
||
compositor=${compositor/\"} # suppression premier"
|
||
compositor=${compositor/\"*} # suppression 2e " avec éventuels caractères suivants
|
||
compositor="Muffin v$compositor"
|
||
fg_wm=${fg_wm/ (muffin)} # suppression (muffin) dans wm
|
||
fi
|
||
# Gnome2, Metacity
|
||
# XFCE, rien pour Xfwm4
|
||
|
||
# en aveugle, pour test et adaptations futures
|
||
[[ "$wm_brut" =~ compiz ]] && compositor+='compiz'
|
||
[[ "$wm_brut" =~ compton ]] && compositor+='compton'
|
||
[[ "$wm_brut" =~ dwc ]] && compositor+='dwc'
|
||
[[ "$wm_brut" =~ fireplace ]] && compositor+='fireplace'
|
||
[[ "$wm_brut" =~ gnome-shell ]] && compositor+='gnome-shell'
|
||
[[ "$wm_brut" =~ grefson ]] && compositor+='grefson'
|
||
[[ "$wm_brut" =~ kmscon ]] && compositor+='kmscon'
|
||
[[ "$wm_brut" =~ kwin ]] && compositor+='kwin'
|
||
[[ "$wm_brut" =~ moblin ]] && compositor+='moblin'
|
||
[[ "$wm_brut" =~ rustland ]] && compositor+='rustland'
|
||
[[ "$wm_brut" =~ sway ]] && compositor+='sway'
|
||
[[ "$wm_brut" =~ swc ]] && compositor+='swc'
|
||
[[ "$wm_brut" =~ wayhouse ]] && compositor+='wayhouse'
|
||
[[ "$wm_brut" =~ westford ]] && compositor+='westford'
|
||
[[ "$wm_brut" =~ weston ]] && compositor+='weston'
|
||
compositor=${compositor^} # caractère 1 en majuscule
|
||
compositor="{$compositor}"
|
||
#final
|
||
fg_wm="$fg_wm $compositor"
|
||
}
|
||
|
||
# aiguillage export paste
|
||
fipaste(){ # 10/11/2017
|
||
f__requis "curl"
|
||
if [ "$?" -gt 0 ]; then
|
||
f__info "une fois Curl installé, inutile de relancer la détection" \
|
||
"$GREEN $DIRNAME""getInfo -p" "pour exporter le rapport existant"
|
||
return 1
|
||
fi
|
||
fipaste_curl_pastery "$fileOutput" "$pasteDuration" "$optDebug"
|
||
# à tester fipaste_curl_markdownshare "$fileOutput"
|
||
}
|
||
|
||
# $1 fichier à exporter, $2 durée de conservation en jour; $3 debug
|
||
fipaste_curl_pastery(){ # 25/10/2017
|
||
[ -e "$1" ] || f__error "fichier $1 inexistant"
|
||
local curl id pluriel
|
||
# curl -X POST "https://www.pastery.net/api/paste/?title=getInfo&language=markdown" -F file=@$1
|
||
# un fichier simple curl https://www.pastery.net/api/paste/ -F file=@data.txt
|
||
curl="$(curl --silent -X POST "https://www.pastery.net/api/paste/?title=getInfo_$version&language=markdown&duration=$(($2*1440))" --data-binary @$1)"
|
||
if grep -q '"result": "error' <<< "$curl" ;then
|
||
f__info "$RED""Erreur critique export rapport:"
|
||
f__info "$curl"
|
||
f__info "merci contacter $projet, $contact pour aider à parfaire le script"
|
||
else
|
||
id="$(echo $curl | cut -d '"' -f 4)"
|
||
[ "$pasteDuration" -gt 1 ] && pluriel="s" || unset pluriel
|
||
f__info "votre paste:$GREEN https://www.pastery.net/$id/" \
|
||
"(valide pendant $RED$pasteDuration jour"$pluriel")"
|
||
echo -e "exporté sur https://www.pastery.net/$id/ \n\n" >> "$fileOutput"
|
||
fi
|
||
[ "$3" == "debugPaste" ] && f__info "$curl"
|
||
# UTF-8
|
||
# ?api_key=<api_key>
|
||
# &duration=<duration> en mn, 1 jour par défaut
|
||
# &language=autodetect possible
|
||
# &max_views=<max_views>
|
||
# 100ko max
|
||
#{"id": "kddgar", "title": "getInfo_2.5.0", "url": "https://www.pastery.net/kddgar/", "language": "markdown", "duration": 1439}
|
||
#{"result": "error", "error_msg": "Your request body was not valid UTF-8."}
|
||
}
|
||
|
||
fipaste_curl_markdownshare(){ # à tester/finir
|
||
[ -e "$1" ] || f__error "fichier $1 inexistant"
|
||
curl -H "Accept: application/json" -X POST -F "text=<$1" https://markdownshare.com/create/
|
||
#-A, --user-agent and -e, --referer options
|
||
#If you wish to allow a post to expire then add an expire= parameter too:
|
||
#expire=Nh Expire in N hours.
|
||
#expire=Nd Expire in N days.
|
||
#-d expire ? ou --data expire
|
||
}
|
||
|
||
# inscription dans tache upgrade en anacron hebdomadaire, via cron horaire, $1=upgrade|install|remove
|
||
fscript_cronAnacron(){ # 4/12/2017
|
||
local dirAnacron dirSpool fileAnacron
|
||
|
||
[ "$(type -t fscript_cronAnacron_special)" ] && fscript_cronAnacron_special # test, si fonction spécifique, appel
|
||
dirAnacron="/home/$fu_user/.config/anacron"
|
||
dirSpool="$dirAnacron/spool"
|
||
fileAnacron="$dirAnacron/$script.anacrontab"
|
||
[ "$EUID" -eq 0 ] && sed -i "/$script.anacrontab/d" /etc/crontab
|
||
case "$1" in
|
||
install | upgrade )
|
||
mkdir -p "$dirAnacron"
|
||
# table anacron
|
||
echo "7 10 $script nice $scriptInstall --upgrade 1>/dev/null" > "$fileAnacron" # juste erreurs en syslog
|
||
## anacron journalier pour dev logname
|
||
if [ -e "$fileDev" ]; then
|
||
echo "1 00 $script""Dev nice $scriptInstall --upgrade 1>/dev/null" >> "$fileAnacron"
|
||
fi
|
||
# création spool anacron utilisateur
|
||
mkdir -p "$dirSpool"
|
||
chown -R "$fu_user:" "$dirAnacron" "$dirSpool"
|
||
if [ "$EUID" -eq 0 ]; then
|
||
# crontab pour activation horaire anacron
|
||
echo "@hourly $fu_user /usr/sbin/anacron -t $fileAnacron -S $dirSpool" >> /etc/crontab
|
||
fi
|
||
[ "$(grep "$script" /etc/crontab)" ] || echo f__error "inscription crontab" \
|
||
"certains systèmes semblent poser poser problème, merci de rapporter ce bug à $projet, $contact"
|
||
;;
|
||
remove )
|
||
rm "$dirSpool/$script"* &>/dev/null
|
||
rm "$fileAnacron" &>/dev/null
|
||
rmdir "$dirSpool" "$dirAnacron" &>/dev/null
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# version script en ligne, [$1=update], assigne $versionScript, $script_aJour=ok|ko
|
||
fscript_get_version(){ # 5/12/2017
|
||
local var_temp
|
||
|
||
f__info "raw" "version script en cours: $GREEN$version"
|
||
versionScript=$(wget -q --timeout=15 -O - "$urlScript" | grep -m1 '^version=' | cut -d'=' -f2)
|
||
if [ "$versionScript" ]; then
|
||
if [ "$version" != "$versionScript" ]; then
|
||
[ "$1" == "update" ] && var_temp=", mise à jour en cours" || var_temp=", mise à jour possible"
|
||
script_aJour="ko"
|
||
else
|
||
script_aJour="ok"
|
||
fi
|
||
f__info "version script en ligne: $YELLOW$versionScript$BLUE$var_temp"
|
||
else
|
||
f__info "version script en ligne$RED non accessible"
|
||
fi
|
||
}
|
||
|
||
# installation du script dans le système
|
||
fscript_install(){ # 4/12/2017
|
||
if grep -q 'bin' <<< "$(dirname $0)" ; then
|
||
f__info "$RED""l'installation dans le système doit se faire depuis un script local $GREEN(./$script -i )"
|
||
return 1
|
||
fi
|
||
if [ "$EUID" -ne 0 ]; then
|
||
f__info "vous devez être$RED ROOT$BLUE pour installer ce script dans le système"
|
||
f__sudo "exec $0 -i"
|
||
return $?
|
||
fi
|
||
[ "$(type -t fscript_install_special)" ] && fscript_install_special # test, si fonction spécifique, appel
|
||
f__requis "wget anacron cron" || exit 1
|
||
# install /opt
|
||
mkdir -p /opt/bin/
|
||
cp -d "$(basename $0)" "$scriptInstall"
|
||
ln -s "$scriptInstall" "/usr/bin/$script" &>/dev/null
|
||
chmod 775 "$scriptInstall" # rwx rwx r-x, proprio fu_user
|
||
# cron/anacron install
|
||
fscript_cronAnacron "install"
|
||
# création fichier log
|
||
touch "$scriptLogs"
|
||
chmod 664 "$scriptLogs" # rw- rw- r--, proprio fu_user
|
||
chown "$fu_user:" "$scriptLogs" "$scriptInstall"
|
||
[ -e "$fileDev" ] || rm "$(basename $0)" &>/dev/null ## on efface pas si fileDev (dev)
|
||
f__info "log" "$script $version installé dans le système." "maintenant, appel du script par: $GREEN$script$BLUE (sans ./)"
|
||
}
|
||
|
||
# suppression du script dans le système
|
||
fscript_remove(){ # 4/12/2017
|
||
if ! grep -q 'bin' <<< "$(dirname $0)" ; then
|
||
f__info "$RED""cette fonction doit être appelée depuis le script installé dans le système $GREEN($script -r)"
|
||
return 1
|
||
fi
|
||
if [ ! -x "$scriptInstall" ];then
|
||
f__info "$RED$script n'est pas installé"
|
||
return 1
|
||
fi
|
||
if [ "$EUID" -ne 0 ]; then
|
||
f__info "vous devez être$RED ROOT$BLUE pour supprimer ce script dans le système"
|
||
f__sudo "exec $0 -r"
|
||
return $?
|
||
fi
|
||
[ "$(type -t fscript_remove_special)" ] && fscript_remove_special # test, si fonction spécifique, appel
|
||
# suppression de /opt
|
||
rm "$scriptInstall" &>/dev/null
|
||
unlink "/usr/bin/$script" &>/dev/null
|
||
# cron/anacron remove
|
||
fscript_cronAnacron "remove"
|
||
f__info "log" "$script $version supprimé du système."
|
||
}
|
||
|
||
# mise à jour script si dispo, v2, +update spécifique
|
||
fscript_update(){ # 4/12/2017
|
||
local dirTemp="/tmp/$script-$RANDOM"
|
||
|
||
[ $(type -t fscript_update_special) ] && fscript_update_special # test, si fonction spécifique, appel
|
||
if [ -z "$updateSpecial" ] && ! grep -q 'bin' <<< "$(dirname $0)" ; then
|
||
f__info "$RED""cette fonction doit être appelée depuis le script installé dans le système $GREEN($script -u)"
|
||
return 1
|
||
fi
|
||
fscript_get_version "update"
|
||
if [ "$script_aJour" == "ok" ]; then
|
||
f__info "log" "pas de mise à jour disponible pour $script $version"
|
||
return 0
|
||
fi
|
||
mkdir -p "$dirTemp"
|
||
wget -q --tries=2 --timeout=15 -O "$dirTemp/$script" "$urlScript"
|
||
if [ "$?" != "0" ]; then f__wget_test "$urlScript"; fi
|
||
if grep -q '#!/bin/bash' "$dirTemp/$script" ; then
|
||
cp -d "$dirTemp/$script" "$scriptInstall"
|
||
chmod 775 "$scriptInstall" # rwx rwx r-x, proprio fu_user
|
||
chown "$fu_user:" "$scriptInstall"
|
||
[ -z "$updateSpecial" ] && fscript_cronAnacron "upgrade"
|
||
f__info "log" "$script mis à jour en version $versionScript $updateSpecial"
|
||
else
|
||
rm -rf "$dirTemp/"
|
||
f__error "échec update" "mauvais téléchargement, réessayer plus tard"
|
||
fi
|
||
rm -rf "$dirTemp/"
|
||
}
|
||
|
||
prg_init(){ # 4/12/2017
|
||
|
||
PATH='/usr/sbin:/usr/bin:/sbin:/bin'
|
||
TERM=xterm
|
||
IFS_INI="$IFS"
|
||
IFS=$' \t\n'
|
||
export PATH TERM IFS
|
||
|
||
# whereis script retourne vide si installé
|
||
DIRNAME=$( dirname $0 )
|
||
DIRNAME=${DIRNAME#/usr/bin} # suppression /usr/bin éventuel au début ( lien )
|
||
DIRNAME=${DIRNAME#/opt/bin} # suppression /opt/bin éventuel au début ( install )
|
||
[ "$DIRNAME" ] && DIRNAME+="/"
|
||
|
||
# aucune erreur visible, prévoir option --debug
|
||
# exec 2>/dev/null
|
||
# exec 2>"$script.log" # à tester
|
||
|
||
# test bash v4
|
||
[ "$BASH_VERSINFO" == 4 ] || f__error "bash v4 requis" "version installée: $BASH_VERSION"
|
||
|
||
# test /proc
|
||
[ -e /proc/cpuinfo ] || f__error "/proc/cpuinfo non trouvé" "/proc ne doit pas être monté"
|
||
|
||
# test OS
|
||
OS=$(uname -s)
|
||
[[ ${OS,,} =~ linux || ${OS,,} =~ gnu ]] && OS="linux"
|
||
[[ ${OS,,} =~ bsd || ${OS,,} =~ Bitrig || ${OS,,} =~ DragonFly ]] && OS="bsd"
|
||
[[ ${OS,,} =~ cygwin || ${OS,,} =~ msys || ${OS,,} =~ mingw ]] && OS="windows"
|
||
[ "$OS" == "bsd" ] && f__info "ce script pour Linux n'est pas prévu de fonctionner sur BSD..."
|
||
[ "$OS" == "windows" ] && f__info "ce script pour Linux n'est pas prévu de fonctionner sous windows..."
|
||
[ "$OS" != "linux" ] && f__error "Linux requis"
|
||
|
||
# recherche wayland
|
||
[ "$(ps -ef | grep -c 'wayland')" -gt 1 ] && wayland="wayland"
|
||
[ "$WAYLAND_DISPLAY" ] && wayland="wayland"
|
||
|
||
# test SSH
|
||
[[ "$SSH_CLIENT" || "$SSH_CLIENT" || "$SSH_CLIENT" ]] && ENV_SSH="ssh"
|
||
# test $DISPLAY
|
||
[ -z "$DISPLAY" ] && ENV_DISPLAY="no DISPLAY"
|
||
|
||
# détermination user derrière root
|
||
f__user
|
||
retourFUser="$?"
|
||
[ "$retourFUser" -eq 1 ] && f__error "user indéterminé" \
|
||
"pour contourner, lancer le script avec:\n$GREEN USER_INSTALL=<user> $0 \n"
|
||
if [ "$retourFUser" -eq 2 ]; then
|
||
[ "$EUID" -eq 0 ] && fu_user="root" || f__error "user détecté, mais pas de home: /home/$fu_user"
|
||
f__info "user root"
|
||
fi
|
||
|
||
# requis pour fonctionnement programme
|
||
f__requis "gawk wget ip>iproute2 lspci>pciutils wc>coreutils" || exit 1
|
||
|
||
# detect rapide systeme deb
|
||
[ $( f__which dpkg ) ] && ENV_DEBIAN="oui"
|
||
}
|
||
prg_1(){ # début 2/12/2017
|
||
echo > "$fileOutput"
|
||
chown $fu_user: "$fileOutput" &>/dev/null
|
||
chmod 666 "$fileOutput" &>/dev/null # rw-rw-rw-, si root permet écriture & effacement à tous
|
||
echo -e "* **$script** sur *$(uname -n)* \n" > "$fileOutput"
|
||
echo -e "$ligneRapport \n" >> "$fileOutput"
|
||
echo -e "--- \n" >> "$fileOutput"
|
||
}
|
||
prg_2(){ # traitements principaux 1/12/2017
|
||
if [[ "$1" == all || "$1" =~ s ]]; then #systeme, matériel -cs
|
||
echo -e "# ▷ Système" >> "$fileOutput"
|
||
for i in fi_system fi_cpu fi_mem fi_hw fi_batt fi_gpu fi_net fi_audio fi_bluez fi_usb fi_disk ; do
|
||
echo -n "•"
|
||
$i
|
||
done
|
||
fi
|
||
if [[ "$1" == all || "$1" =~ c ]]; then #configuration #debian, packages -cc fi_conf
|
||
echo -e "# ▷ Configuration" >> "$fileOutput"
|
||
for i in fi_locale fi_conf fi_vrms fi_packagers ; do
|
||
echo -n "•"
|
||
$i
|
||
done
|
||
fi
|
||
if [[ "$1" == all || "$1" =~ r ]]; then #reseau -cr
|
||
echo -e "# ▷ Réseau" >> "$fileOutput"
|
||
for i in fi_reseau fi_nm ; do
|
||
echo -n "•"
|
||
$i
|
||
done
|
||
fi
|
||
if [[ "$1" == all || "$1" =~ a ]]; then #analyse -ca
|
||
echo -e "# ▷ Analyse" >> "$fileOutput"
|
||
for i in fi_efi fi_system_analyse fi_log_xorg fi_journal ; do
|
||
echo -n "•"
|
||
$i
|
||
done
|
||
fi
|
||
[[ "$1" == all ]] || f_dspl_md "$fileOutput"
|
||
}
|
||
prg_3(){ # fin de traitements
|
||
echo -e "--- \n" >> "$fileOutput"
|
||
echo -e "$ligneRapport \n" >> "$fileOutput"
|
||
f__dialog_oui_non "non" "\n exporter sur le pastebin par défaut?" && fipaste
|
||
f__info "le rapport est disponible en local, fichier:$YELLOW $fileOutput" \
|
||
"vous pouvez le visualiser ultérieurement avec $GREEN$script -l" \
|
||
"vous pourrez l'exporter ultérieurement avec $BLUE$script -p"
|
||
}
|
||
prg_menu(){ # 5/12/2017
|
||
|
||
function display_menu {
|
||
local centre=50 left=2 larg=60 reply line
|
||
if [ $(( $(tput cols) )) -le 80 ]; then
|
||
centre=$(( $(tput cols)/2+$left ))
|
||
larg=$(( $centre+3*$left ))
|
||
fi
|
||
tput cud 1
|
||
tput hpa $left
|
||
printf '%.'$larg's' "$1"
|
||
tput hpa $centre
|
||
printf '%.'$larg's' "$2"
|
||
}
|
||
|
||
echo -en " $GREEN$script -h$STD : afficher l'aide \n"
|
||
display_menu "$GREEN$script -c$RED""s$STD : catégorie système" \
|
||
"$GREEN$script -c$RED""c$STD : catégorie configuration"
|
||
display_menu "$GREEN$script -c$RED""r$STD : catégorie réseau" \
|
||
"$GREEN$script -c$RED""a$STD : catégorie analyse"
|
||
echo -e "\n\n les catégories peuvent être cumulées: \n" \
|
||
" $GREEN$script -c$RED""sa$STD générera un rapport sur le système & l'analyse"
|
||
echo -en "\n ( ne pas saisir le préfixe $YELLOW-c$STD, all par défaut)\n"
|
||
echo -en "\n choix des catégories à générer (all pour toutes)? "
|
||
read reply
|
||
[ "$reply" ] && reply="-c${reply,,}" || reply="all"
|
||
reply="$(sed 's/-call/all/' <<< $reply)"
|
||
exec $0 "$reply"
|
||
}
|
||
|
||
######## début script / initialisation
|
||
|
||
# logo et définition couleurs
|
||
f_affichage
|
||
|
||
# tests au démarrage
|
||
prg_init
|
||
|
||
options=$@
|
||
# traitement option paramètres
|
||
for j in $options; do
|
||
case $j in
|
||
--debug-paste )
|
||
optDebug="debugPaste"
|
||
;; # si debug, retour json de pastery.net
|
||
-t* )
|
||
pasteDuration="$(sed -En 's/-t([0-9]+)/\1/p' <<< $j)"
|
||
;; # durée de conservation standard du paste en jours
|
||
esac
|
||
done
|
||
options="$(sed -E 's/--debug-paste//g; s/-t[0-9]+//g' <<< $options | xargs)" # nettoyage options
|
||
|
||
[ "$options" ] || options="all"
|
||
|
||
# paramètres généraux
|
||
[ "$pasteDuration" ] || pasteDuration=7 # durée de conservation standard du paste en jours
|
||
fileOutput="getInfo_rapport.md"
|
||
scriptInstall="/opt/bin/$script"
|
||
scriptLogs="/var/log/sdeb_$script.log"
|
||
fileDev="/opt/bin/fileDev"
|
||
urlScript="https://frama.link/getInfo"
|
||
urlNotice="https://frama.link/doc-getInfo"
|
||
# test sur frama.link ok, sinon fallback sur framagit
|
||
if [[ "$options" =~ all|-d|-h|-c|-v ]]; then
|
||
if ! f__wget_test "$urlScript" "test"; then
|
||
urlScript="https://framagit.org/kyodev/kyopages/raw/master/scripts/$script"
|
||
urlNotice="https://kyodev.frama.io/kyopages/scripts/getInfo/"
|
||
fi
|
||
fi
|
||
|
||
spc5=$'\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0'
|
||
ligneRapport="Rapport du $(date '+%d/%m/%Y %H:%M %z')$spc5◇$spc5$0 $*$spc5◇$spc5[$script $version]($urlNotice)"
|
||
|
||
# traitement options menu catégories
|
||
for k in $options; do
|
||
categorie+="$(sed -En 's/-c([a-z]+)/\1/p' <<< $k)"
|
||
options="$(sed -E 's/-c[a-z]+//' <<< $k | xargs)"
|
||
done
|
||
[ "$categorie" ] && options+=" -c$categorie"
|
||
# actions
|
||
for j in $options; do
|
||
case $j in
|
||
-t | --test )
|
||
ORIGIN='test'
|
||
prg_1 "$*"
|
||
echo -n "•"
|
||
fi_cpu
|
||
echo; f_dspl_md "$fileOutput"
|
||
exit ;; # test
|
||
-c* | all )
|
||
[ "$j" == "-c" ] && exec $0 "menu"
|
||
prg_1 "$*"
|
||
j=$(sed -E 's/-c//' <<< $j)
|
||
prg_2 "$j"
|
||
prg_3
|
||
exit ;; # rapport complet ou par catégorie
|
||
-dx )
|
||
prg_1 "$*"
|
||
fi_gpu "xorgOnly"
|
||
f_dspl_md "$fileOutput"
|
||
exit ;; # essai détail, xorgOnly
|
||
-dp )
|
||
prg_1 "$*"
|
||
fi_pkg_apt "confOnly"
|
||
f_dspl_md "$fileOutput"
|
||
exit ;; # essai util source/apt confOnly
|
||
-j )
|
||
prg_1 "$*"
|
||
prg_2 "a"
|
||
exit ;; # exporte le rapport existant
|
||
-l )
|
||
f_dspl_md "$fileOutput"
|
||
exit ;; # afficher le rapport existant
|
||
-p )
|
||
fipaste
|
||
exit ;; # exporte le rapport existant
|
||
-h )
|
||
f_help
|
||
exit ;; # affichage help
|
||
--ip )
|
||
if figet_ip_pub "4" ; then
|
||
f__info "raw" " ipv4 publique: $GREEN$fg_public"
|
||
else
|
||
f__info "$BLUE pas de connectivité ipv4"
|
||
fi
|
||
if figet_ip_pub "6" ; then
|
||
f__info "raw" " ipv6 publique: $GREEN$fg_public"
|
||
else
|
||
f__info "$BLUE pas de connectivité ipv6"
|
||
fi
|
||
exit ;; # affiche ip public
|
||
--mac )
|
||
figet_ip
|
||
f__info "fg_mac:\n$GREEN$fg_mac_tp"
|
||
exit ;; # affiche adresses mac
|
||
--serial )
|
||
fi_serial
|
||
exit ;; # affiche n° série
|
||
--ssid )
|
||
fi_ssid
|
||
exit ;; # affiche configurations ssid, root requis
|
||
-i | --install )
|
||
fscript_install
|
||
exit ;; # installation du script dans le système
|
||
-r | --remove )
|
||
fscript_remove
|
||
exit ;; # suppression du script dans le système
|
||
-u | --upgrade )
|
||
opType="upgrade" # log si f__error
|
||
fscript_update
|
||
exit ;; # upgrade script si maj possible
|
||
-us )
|
||
opType="upgrade" # log si f__error
|
||
updateSpecial="update spécial actif"
|
||
scriptInstall="$(dirname $0)/$script"
|
||
fscript_update
|
||
exit ;; # upgrade spécial
|
||
-v | --version )
|
||
fscript_get_version
|
||
exit ;; # version du script, en ligne et exécuté
|
||
menu | * )
|
||
prg_1 "$*"
|
||
prg_menu
|
||
exit ;; # affichage help
|
||
esac
|
||
done
|
||
|
||
exit 0
|
||
|
||
wget -nv -O getInfo https://frama.link/getinfo
|
||
chmod +x getInfo && ./getInfo
|
||
|
||
wget -nv -O getInfo https://framagit.org/kyodev/kyopages/raw/master/scripts/getInfo
|
||
|
||
### END CONTROL (contrôle chargement)
|