J'ai besoin d'écrire un script qui écrit dans un fichier combien de fois ce script a été exécuté.
Comment puis je faire ça?
Je suppose que vous voulez avoir un seul fichier countfile
qui ne contient qu'un seul nombre représentant le compteur d'exécution.
Vous pouvez lire ce compteur dans une variable shell $counter
par exemple. en utilisant l'une de ces lignes:
read counter < countfile
counter=$(cat countfile)
Des additions entières simples peuvent être effectuées dans Bash lui-même en utilisant la syntaxe $(( EXPRESSION ))
. Ensuite, écrivez simplement le résultat dans notre countfile
:
echo "$(( counter + 1 ))" > countfile
Vous devriez probablement également protéger votre script pour le cas où countfile
n'existe pas encore et en créer un initialisé avec la valeur 1.
Le tout pourrait ressembler à ceci:
#!/bin/bash
if [[ -f countfile ]] ; then
read counter < countfile
else
counter=0
fi
echo "$(( counter + 1 ))" > countfile
Cette solution utilise la même approche que réponse de Byte Commander mais elle ne repose pas sur l’arithmétique Shell ni sur d’autres bashismes.
exec 2>&3 2>/dev/null
read counter < counter.txt || counter=0
exec 3>&2 3>&-
expr "$counter" + 1 > counter.txt
Les redirections de flux
/dev/null
(pour supprimer le message d'erreur dans la redirection ultérieure de l'entrée de la commande read
si le fichier de compteur manque de manière attendue),Laissez simplement le script créer un fichier journal, ajoutez par exemple une ligne dans votre script à la fin:
echo "Script has been executed at $(date +\%Y-\%m-\%d) $(date +\%H-\%M-\%S)" >> ~/script.log
De cette façon, vous pouvez formater vous-même la manière dont vous présentez la date et l'heure, mais si vous voulez simplement utiliser une date et une heure complètes (et HH:MM:SS
est un format acceptable pour vous), vous pouvez aussi simplement utiliser:
echo "Script has been executed at $(date +\%F-\%T)" >> ~/script.log
Ensuite, vous pourriez faire:
wc -l ~/script.log
Ce qui compte les caractères de nouvelle ligne et vous donne une estimation du nombre de lignes contenues dans le fichier journal. Jusque-là, vous pouvez voir dans le fichier journal même quand il a été exécuté. Pour l'adapter à vos besoins, vous pouvez modifier les chemins et les noms utilisés pour la journalisation. Je viens de faire un exemple ici qui enregistre le fichier journal dans ~
.
Ainsi, par exemple, si vous voulez que le script ajoute ce nombre à la ligne que vous avez ajoutée à la fin de votre script, vous pouvez faire quelque chose comme ceci au début de votre script:
count=$(( $(wc -l ~/script.log | awk '{print $1}') + 1 ))
# the next line can be simply skipped if you not want an output to std_out
echo "Script execution number: $count"
Et changez votre ligne à la fin du script en quelque chose incluant même cette information:
echo "Script has been executed $count times at $(date +\%F-\%T)" >> ~/script.log
Un fichier compteur séparé a des inconvénients:
Donc, cette réponse supprime un fichier compteur séparé et met le compte dans le script bash lui-même!
flock
garantit que pendant un bref instant, il n'est pas possible pour deux utilisateurs d'exécuter le script en même temps.#!/bin/bash
# NAME: run-count.sh
# PATH: $HOME/bin
# DESC: Written for AU Q&A: https://askubuntu.com/questions/988032/how-can-i-cause-a-script-to-log-in-a-separate-file-the-number-of-times-it-has-be
# DATE: Mar 16, 2018.
# This script run count: 0
# ======== FROM HERE DOWN CAN GO INTO FILE INCLUDED WITH SOURCE COMMAND =======
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
# This is useful boilerplate code for Shell scripts. Put it at the top of
# the Shell script you want to lock and it'll automatically lock itself on
# the first run. If the env var $FLOCKER is not set to the Shell script
# that is being run, then execute flock and grab an exclusive non-blocking
# lock (using the script itself as the lock file) before re-execing itself
# with the right arguments. It also sets the FLOCKER env var to the right
# value so it doesn't run again.
# Read this script with entries separated newline " " into array
mapfile -t ScriptArr < "$0"
# Build search string that cannot be named
SearchStr="This script"
SearchStr=$SearchStr" run count: "
# Find our search string in array and increment count
for i in ${!ScriptArr[@]}; do
if [[ ${ScriptArr[i]} = *"$SearchStr"* ]]; then
OldCnt=$( echo ${ScriptArr[i]} | cut -d':' -f2 )
NewCnt=$(( $OldCnt + 1 ))
ScriptArr[i]=$SearchStr$NewCnt
break
fi
done
# Rewrite our script to disk with new run count
# BONUS: Date of script after writing will be last run time
printf "%s\n" "${ScriptArr[@]}" > "$0"
# ========= FROM HERE UP CAN GO INTO FILE INCLUDED WITH SOURCE COMMAND ========
# Now we return you to your original programming....
exit 0
Semblable à la réponse de Videonauth, j’ai écrit un journal contenant les réponses suivantes: script Bash pour conserver la trace de l’audit/le journal des fichiers consultés pour consigner chaque fois que des pouvoirs racine ont été utilisés avec gedit
ou nautilus
.
Le problème est que plutôt que d'utiliser gksu
le script s'appelle gsu
et invoque pkexec
la manière "moderne" d'utiliser Sudo dans l'interface graphique, me dit-on.
Un autre avantage est non seulement d'indiquer à chaque fois que les puissances root ont été utilisées avec gedit
, mais également de consigner le nom du fichier qui a été modifié. Voici le code.
~/bin/gsu
:
#!/bin/bash
# Usage: gsu gedit file1 file2...
# -OR- gsu natuilus /dirname
# & is used to spawn process and get Prompt back ASAP
# > /dev/null is used to send gtk warnings into dumpster
COMMAND="$1" # extract gedit or nautilus
pkexec "$COMMAND" "${@:2}"
log-file "${@:2}" gsu-log-file-for-"$COMMAND"
/usr/local/bin/log-file
:
#! /bin/bash
# NAME: log-file
# PATH: /usr/local/bin
# DESC: Update audit trail/log file with passed parameters.
# CALL: log-file FileName LogFileName
# DATE: Created Nov 18, 2016.
# NOTE: Primarily called from ~/bin/gsu
ABSOLUTE_NAME=$(realpath "$1")
TIME_STAMP=$(date +"%D - %T")
LOG_FILE="$2"
# Does log file need to be created?
if [ ! -f "$LOG_FILE" ]; then
touch "$LOG_FILE"
echo "__Date__ - __Time__ - ______File Name______" >> "$LOG_FILE"
# MM/DD/YY - hh:mm:ss - "a/b/c/FileName"
fi
echo "$TIME_STAMP" - '"'"$ABSOLUTE_NAME"'"' >> "$LOG_FILE"
exit 0
Contenu du fichier journal gsu-log-file-for-gedit
après quelques modifications:
__Date__ - __Time__ - ______File Name______
11/18/16 - 19:07:54 - "/etc/default/grub"
11/18/16 - 19:08:34 - "/home/rick/bin/gsu"
11/18/16 - 19:09:26 - "/home/rick/bin/gsu"