Script Bash Terminal (infos, màj et prompt)

echolib terminal info upgraded info script

Utilisant de plus en plus le terminal de mon #ArchLinux, j'ai eu envie de créer un script utile, capable de m'apporter dedans des informations sur mon système, lorsque je l'ouvre. Ce code permet de gérer les mises à jour, me montrer la météo plutôt complète (et la phase de la lune) du moment, la mémoire libre et utilisée, la charge système, etc, le tout dans un format “compact”. Par la même occasion, je vous propose aussi d'améliorer le prompt (inclus). Maintenant, je ne peux plus m'en passer...

Installation

Les instructions (en français) pour l'installer sont au début du script en commentaires, et j'ai commenté (en anglais) une bonne partie du code Shell #bash. Tout ce que je vous demande, si vous le partagez, le modifiez ou le copiez, c'est de citer ce lien source original (Licence CC-By).

Ce code est à mettre dans le fichier .bashrc-sysupgrade que vous pouvez créer. Il faudra ensuite le renseigner dans le fichier source .bashrc et d'y ajouter ensuite la commande showterm.

Utilisation

L'interval de mise à jour en minutes pour la recherche des mises à jour est modifiable par la variable tmvall. Par défaut, la recherche se fera toutes les deux heures. Vous pouvez forcer la recherche avec la commande update. Pourquoi 2 heures ? Parce que si vous lancez régulirement votre terminal, celui-ci n'aura pas de latence au démarrage, les informations étant lues dans des fichiers.

Pour afficher les mises à jour sous la forme d'une liste, tapez la commande lsupd, et pour mettre à jour tapez la commande upgrader. Enfin, au besoin, la commande rlbash relance sans quitter le terminal les nouvelles modifications apportées à vos fichiers. Je me suis servi du service “wttr” pour afficher les informations météo. La fonction showterm est le point de départ du script et si vous ne voulez pas de cette météo, commentez la ligne dans cette fonction. Enfin, sachez que ce script va créer un dossier caché .updated dans lequel plusieurs fichiers de gestion seront placés.

Origine et Disclamer

Tout est parti de la commande checkupdates qui permet de vérifier la disponibilité de nouvelles mises à jour, sans passer par sudo. Pour fonctionner, ce script nécessite archlinux (#pacman) et le shell bash. Ce script n'est sûrement pas parfait, mais il fonctionne et je le trouve bien utile, alors je le partage.

Démonstration

Des images valant mieux qu'un long discours, voici ce qu'il fait.

echolib terminal prompt info script echolib terminal lsupd info echolib terminal info upgraded info script echolib terminal info script prompt folder

Script CC-By echolib

#
# ~/.bashrc-sysupgrade
#
# Instructions :
# - Copier ce fichier (.bashrc-sysupgrade) ou créer le avec ce contenu dans la racine GNU/Linux de votre dossier personnel
# - Dans le fichier .bashrc, copier ce code : (Ligne 7 et 8 sans le '#')
# 		[[ -f ~/.bashrc-sysupgrade ]] 	&& . ~/.bashrc-sysupgrade
#		showterm
# 
# Fonctions de vérifications (sans sudo) et de mises à jour du système
# Avec affichage et recherche sous conditions au démarrage du Terminal
# NECESSITE archlinux ou dérivée utilisant PACMAN et testé avec BASH uniquement
#
# Par echolib. (echolib.in) - Mastodon: @echolib@framapiaf.org
# Blog : https://echolib.in/script-bash-terminal-infos-maj-prompt
#

# La commande "update" force la recherche de mise à jour et relance l'affichage des informations.
# Recherche des mises à jour toutes les 2 heures automatiquement
# La commande lsupd affiche la liste des paquets nouvellement disponibles

# La commande "rlbash" (Reload bash) re-source sans quitter le terminal les ficiers modifiés
# (modifier le nom du fichier source ci-dessous si nécessaire)
alias rlbash='clear;source ~/.bashrc'

# Some Colors

RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
PURPLE='\033[0;35m'
ORANGE='\033[0;33m'
LGRAY='\033[0;37m'
DGRAY='\033[1;30m'
LBLUE='\033[1;34m'
LGREEN='\033[1;32m'
LCYAN='\033[1;36m'
LRED='\033[1;31m'
LPURPLE='\033[1;35m'
YELLOW='\033[1;33m'
WHITE='\033[1;37m'
NC='\033[0m'

# Defaut PS1 : [\u@\h \W]\$
# Delete this Section to get normal prompt back
# Begin new Prompt ; best with black terminal

function ps1_uh { 
	echo -e "\[\033[1;32m\]\u\[\033[0m\] @\[\033[0;37m\]\h\[\033[0m\]"
}
function ps1_dir {
	echo -e "\n>>> \[\$(/bin/ls -1 | /usr/bin/wc -l | /bin/sed 's: ::g') fichiers, \$(/bin/ls -lah | /bin/grep -m 1 total | /bin/sed 's/total //')\]b > \[\033[1;33m\]\w\[\033[0m\]"
}
function ps1_prompt {
	echo -e "\n\[\033[0;37m\]$>\[\033[0m\] "
}

PS1="\n\[\$(if [ \$? == 0 ]; then echo '\[\033[0;32m\]\A\[\033[0m\]'; else echo '\[\033[0;33m\]\A\[\033[0m\]'; fi)\]: $(ps1_uh)$(ps1_dir)$(ps1_prompt)"
# End new Prompt

function wttr {
    # wttr metep function (where automatic IP detected)
		local request="wttr.in/"
		[ "$(tput cols)" -lt 125 ] && request+='?format=%c+%t+"%h+%p"+%w+%P+(%M+%m)'
		curl -H "Accept-Language: ${LANG%_*}" --compressed "$request"
}


		# paramètres
		chkupd_file="$HOME/.updated/.time_updated" 	# file to store update date variable
		upgrad_file="$HOME/.updated/.time_upgraded"	# file to store upgrade date variable
		nbrupd_file="$HOME/.updated/.updates_number"	# file to store nummber of updates
		nbrkrn_file="$HOME/.updated/.krnlupd_number" 	# file to store number of kernel updates
		tmkrnl_file="$HOME/.updated/.krnltm_upgraded"	# file to store date of upgraded kernel
		pkgupd_file="$HOME/.updated/.pkgupdates"		# file to store names and versions to update
										
		tmvall=120							# Valeur limite en minutes pour recréer l'indicateur de temps et vérifier les MAJ
		tmvalm=60 							# Valeur en minutes
		tmvalh=3600 						# Valeur en secondes
		tmvalj=86400						# Valeur en jours
		upsince=$(cat /proc/stat | grep btime | awk '{ print $2 }') 	# Up Since last boot
		
		# alias meteo if needed - commande 'meteo"
		alias meteo='curl wttr.in/?format="?format=%c+%t+"%h+%p"+[%w+%P]+(%M+%m)'
		
function connected {
	# Check if connected (Local)
		ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null 2>&1 && isconnected=true || isconnected=false
		if	[ "$isconnected" == false ];then
				pcol=${YELLOW}
				echo -e "#  "$pcol"Internet est déconnecté ! ${NC}"
				echo
				return
		else
			pcol=${GREEN}
		fi
}

function time_analyse {
	# Update time check only
		readtimeupd=$(sed -n '1p' $chkupd_file)					# Read file for updated time
		if 	[ "$readtimeupd" == "0" ];then
				difftimeupd_m=$(( $tmvall + 1 ))				# First time launch. Force updating
		else
			difftimeupd=$(( $(date +%s) - $readtimeupd ))		# Print date of update time
			difftimeupd_m=$(( $difftimeupd / $tmvalm ))			# Convert in Minutes
			difftimeupd_h=$(( $difftimeupd / $tmvalh ))			# Convert in Hours
		fi
	
	#UpGrade time check only
		readtimeupg=$(sed -n '1p' $upgrad_file)					# Read file for upgraded time
		if	[ ! "$readtimeupg" == "0" ];then				
				difftimeupg=$(( $(date +%s) - $readtimeupg ))	# Print GNU date of upgrade time
				difftimeupg_m=$(( $difftimeupg / $tmvalm ))		# Convert in Minutes
				difftimeupg_h=$(( $difftimeupg / $tmvalh ))		# Convert in Hours
				difftimeupg_j=$(( $difftimeupg / $tmvalj ))		# COnvert in days
		fi
}

function create_empty_files {
	# Create files needed to check time and variables (if not exist) in ".updated" folder
		if	[ ! -d "$HOME/.updated" ];then 
				mkdir $HOME/updated
				mv $HOME/updated $HOME/.updated
		fi
		[ ! -f "$chkupd_file" ] 	&& echo "0" > $chkupd_file			# Store time of update
		[ ! -f "$upgrad_file" ] 	&& date +%s > $upgrad_file			# Store time of Upgrade
		[ ! -f "$nbrupd_file" ] 	&& echo "0" > $nbrupd_file			# Store number of updates
		[ ! -f "$tmkrnl_file" ]		&& echo $upsince > $tmkrnl_file		# Store time of kernel upgrade
		[ ! -f "$nbrkrn_file" ] 	&& echo "0" > $nbrkrn_file			# Store number of kernel updates
		[ ! -f "$pkgupd_file" ]		&& echo > $pkgupd_file				# Store datas of packages available
}

function before_updater {
	# Processes before updater function
		connected 				# Check for alive Internet
		create_empty_files 		# (if needed)
		time_analyse
}

function updater {
	# process to check without sudo if updates exists
		before_updater
		if	[ "$difftimeupd_m" -ge "$tmvall" ];then				
				checkupdates > $pkgupd_file							# Print in file updates availables, line by line
				chkupd=$(<$HOME/.updated/.pkgupdates)						# Save in $chkupd datas (packages and infos) for updates
				nbrupd=$(wc -l <<< $chkupd)							# Analyse number of lines (to know how many packages can be updated)
				noupd=$(tail -1 <<< $chkupd)						# If there is no update available
				nbrkrn=$(printf "$chkupd" | grep -c '\<linux\>')	# Analyse if kernel can be updated. Print number
				after_updater
		fi
}

function after_updater {
	# Processes after updater function
		date +%s > $chkupd_file																# Print date after checking for updates
		[ -z "$noupd" ]			&& echo "0" > $nbrupd_file	|| echo $nbrupd > $nbrupd_file	# Print number of updates in file if exist
		[ "$nbrkrn" -lt 1 ] 	&& nbrkrn=0													# Put 0 if no Kernel update
		echo $nbrkrn > $nbrkrn_file															# Print number of kernel updates in file 
		time_analyse
}

function upgrader {
	# All Upgrade and clean from pacman
		before_updater
		clear
		echo
		echo "#  Recherche des Mises à jour du système..."
		echo -e "#  ${YELLOW}sudo pacman -Syyq --color always${NC}"
		echo
		sudo pacman -Syyq --color always
		sleep 4
		clear
		echo "#  Installation des nouvelles versions ?"
		echo -e "#  ${YELLOW}sudo pacman -Su --color always${NC}" 
		echo
		sudo pacman -Su --color always
		echo
		clnpkg
		# for youtube-dl if is install manually. Uncomment these 2 lines
		# echo "#  Mise à jour de youtube-dl"
		# echo -n "-  ";sudo youtube-dl -U
		after_upgrader
}

function after_upgrader {
	# Some Checking for updater functions and terminal show
		ifkrn=$(sed -n '1p' $nbrkrn_file) 				# Store Value of kernel update
		[ "$ifkrn" -ge 1 ] && date +%s > $tmkrnl_file	# Store date of upgrade kernel
		date +%s > $upgrad_file							# Print date of upgrade in file
		date +%s > $chkupd_file 						# Print date of update, as upgraded
		echo "0" > $nbrupd_file 						# Print 0 as upgraded
		echo "0" > $nbrkrn_file 						# Print 0 as upgraded
		echo "" > $pkgupd_file							# Clean datas in file
}

function getinfo_updater {
	# Get info and analyse from file
		processus=$(ps aux | wc -l)
		memfree=$(free | awk '{print $7}' | head -2 | tail -1)
		memused=$(free | awk '{print $3}' | head -2 | tail -1)
		showupd=$(sed -n '1p' $nbrupd_file)
		ifkrn=$(sed -n '1p' $nbrkrn_file)
		iftmkrn=$(sed -n '1p' $tmkrnl_file)
		[ ! "$ifkrn" == 0 ]		&& pcol='\033[1;33m' || pcol='\033[0;32m'		# yellow if new kernel else green									# No kernel updated
		[ "$showupd" -le 1 ] 	&& pluriel="" || pluriel="s"					# to show correct sentences if more (french)
		 		
		# Dates, times and loads 																								
		uptm=$(awk '{printf("%dj %02d:%02d:%02ds\n",($1/60/60/24),($1/60/60%24),($1/60%60),($1%60))}' /proc/uptime)	# Elapsed time from start
		started=$(date -d "$(uptime -s)" "+Démarré le %d-%m-%Y")													# To echo FR date of start
		loadaverage=$(uptime | grep -o 'load.*')																	# Load Average of system
		
		# If kernel updated, and computer needs restart
		if	[ "$upsince" -lt "$iftmkrn" ];then
				pcol='\033[1;33m' 											# Yellow Color
				needstart=" => ${RED}Redémarrage${NC}"
		else
				needstart=""		# Show if restart is needed
		fi

		# Show time for updated search
		[ "$difftimeupd" -lt 20 ] 								&& showdifftimeupd="à l'instant !"
		[ "$difftimeupd" -ge 20 ] && [ "$difftimeupd" -le 59 ]	&& showdifftimeupd=$difftimeupd"s"
		[ "$difftimeupd_m" -ge 1 ] 								&& showdifftimeupd=$difftimeupd_m"m"
		[ "$difftimeupd_m" -ge 59 ] 							&& showdifftimeupd=$difftimeupd_h"h"
		
		# Show time for upgraded system
		[ "$difftimeupg" -le 59 ] 									&& showdifftimeupg=$difftimeupg"s"
		[ "$difftimeupg_m" -ge 1 ]									&& showdifftimeupg=$difftimeupg_m"m"
		[ "$difftimeupg_m" -ge 59 ] && [ "$difftimeupg_h" -le 24 ]	&& showdifftimeupg=$difftimeupg_h"h"
		[ "$difftimeupg_j" -ge 1 ]									&& showdifftimeupg=$difftimeupg_j"j"
		[ "$readtimeupg" == 0 ]										&& showupg="\033[1;31m NC \033[0m" 	|| showupg="\033[0;32m$showdifftimeupg\033[0m" 	# Show time from last upgrade system
		
		# if clean is needed
		cleanpkg=$('pacman' -Qdtq >> /dev/null)
		[ "$?" = 0 ] && showclean=" - \033[1;33mclnpkg\033[0m"
}

function showterm {
	# Show infos at terminal start
		echo
		echo -e "#  ${CYAN}$(date +%c)${NC}"
		echo -n "#  ";wttr						# Meteo
		echo
		updater
		getinfo_updater
		echo -e "#  $(uname -o) $(uname -m) -" $pcol$(uname -r)${NC}$needstart
		echo "#  $started ($uptm)"
		echo -ne "#  $loadaverage - $processus processus - Mém. : \033[1;33m$memused\033[0m/\033[0;32m$memfree\033[0m Mo";echo
		echo -e "#  Système mis à jour: $showupg (Recherche : ${GREEN}$showdifftimeupd${NC})$showclean"
		[ "$showupd" == 0 ] 	&& echo -e "#  ${GREEN}Aucune mise à jour disponible ${NC}"
		[ "$showupd" -ge 1 ]	&& echo -e "#  ${YELLOW}$showupd mise$pluriel à jour disponible$pluriel${NC} (taper ${GREEN}lsupd${NC} ou ${YELLOW}upgrader${NC})"
}

function lsupd {
	# Show a list of packages that can be updated
		showlsupd=$(<.updated/.pkgupdates)					# File Analyse to get updates infos
		if 	[ -z "$showlsupd" ];then
				echo
				echo -e "#  ${GREEN}Rien à afficher${NC}"
				echo
		else
			echo
			cat .updated/.pkgupdates | column -s ' ' -t -N Paquets,'Ancienne Version','->','Nouvelle Version'	# Get from file
			echo
			echo -e "#  Taper la commande ${YELLOW}upgrader${NC} pour mettre à jour le système"
			echo
		fi
}

function clnpkg {
	# find if clean is needed
	cleanpkg=$(pacman -Qdtq >> /dev/null)
	if	[ "$?" == 1 ];then
			echo -e "#  ${GREEN}Aucune dépendance inutile trouvée.${NC}"
			echo
	else
		echo
		echo "#  Nettoyage des dépendances anciennes..."
		echo -e '#  \033[1;33msudo pacman -Rns $(pacman -Qdtq)\033[0m'
		echo
		sudo pacman -Rns $(pacman -Qdtq)
		echo
	fi
}

function update {
	# update, by simply checking without pacman, using checkupdates
	clear
	tmvall=0
	showterm
}