#1 Le 06/07/2020, à 11:55
- Flashneo
[Résolu] Problème crontab execution script
Bonjour,
Je viens vers vous car je bloque sur un problème d'exécution d'un script avec la crontab.
Pour vous expliquer, j'héberge un serveur minecraft sur mon raspberry et j'ai donc écris un script bash pour pouvoir lancer des sauvegardes automatique du monde.
Le script lors de son exécution doit faire les étapes suivantes :
- Vérifie si le dossier de backup existe sinon le créer
- Envoie un message sur le serveur exécuté dans un screen pour prévenir les joueurs
- Archive de façon incrémental le monde à sauvegarder
- Envoie un message sur le serveur pour prévenir que l'exécution du script est terminé + quelques infos
Mon problème est que lorsque que je lance le script avec la commande :
./backup.sh
Tout ce passe bien, les messages sont envoyé sur le serveur, la sauvegarde est créer. Si c'est la première sauvegarde la taille de l'archive parait logique et contient tout le dossier sauvegardé.
Si je relance le script une seconde fois à la main, l'archivage incremental fonctionne et l'archive créé contient bien uniquement les fichiers modifiés.
Par contre lorsque le script est lancé automatiquement avec la crontab :
0 */3 * * * /home/flashneo/minecraft/backup.sh
Le script se lance bien, le message pour prévenir qu'une sauvegarde commence est bien affiché en jeu, une archive est bien créé mais le problème est qu'elle à une taille ridiculement petite et que le message d'après ne s'affiche pas en jeu...
Je ne sais pas si c'est un problème de droit ou autre car sinon le script ne se lancerais peut-être tout simplement pas ?
Enfin voilà, je viens vers vous car je connais que très peu crontab et je n'arrive pas à solutionner mon problème malgré plusieurs recherches.
Voilà mon fichier backup.sh
#!/bin/bash
################################################################
# #
################################################################
# Configuration ###########################
BACKUP_DIRECTORY="./mnt/library/backupMinecraft"
WORLD_TO_BACKUP="./world"
SCREEN_NAME="serverMinecraft"
ADMIN_PSEUDO="Flashneo"
PREFIX="AutoBackup"
ENABLE_CHAT_MESSAGE=true
ENABLE_ADMIN_MESSAGE=true
CONSOLE_LOG=false
ENABLE_LOG_FILE=true
LOG_FILE="./backup.log"
LOG_ERROR_FILE="./backup.error.log"
###########################################
# Do not modify
DATE_FORMAT="%F_%H%M"
DATE=$(date +$DATE_FORMAT)
ARCHIVE_FILE_NAME=$DATE.tar.gz
ARCHIVE_PATH=$BACKUP_DIRECTORY/$ARCHIVE_FILE_NAME
################################################################
# Minecraft console commands #
################################################################
exec_cmd () {
local COMMAND=$1
if [[ $SCREEN_NAME != "" ]]; then
if screen -ls | grep -q $SCREEN_NAME; then
screen -S $SCREEN_NAME -p 0 -X stuff "$COMMAND$(printf \\r)"
fi
fi
}
send_message () {
if $ENABLE_CHAT_MESSAGE; then
local MESSAGE=$1
exec_cmd "tellraw @a [\"\",{\"text\":\"[\",\"color\":\"white\"},{\"text\":\"$PREFIX\",\"color\":\"dark_gray\"},{\"text\":\"] \",\"color\":\"white\"},{\"text\":\"$MESSAGE\",\"color\":\"gold\"}]"
fi
}
send_message_to_admin () {
if $ENABLE_ADMIN_MESSAGE; then
local MESSAGE=$1
exec_cmd "tellraw $ADMIN_PSEUDO [\"\",{\"text\":\"[\",\"color\":\"white\"},{\"text\":\"$PREFIX\",\"color\":\"dark_gray\"},{\"text\":\"] \",\"color\":\"white\"},{\"text\":\"$MESSAGE\",\"color\":\"gold\"}]"
fi
}
################################################################
# Backup world #
################################################################
backup () {
# Disable world autosaving
exec_cmd "save-off"
send_message "Starting backup of world"
if $CONSOLE_LOG; then
echo "======================================================="
echo "$DATE"
echo "Starting backup of $WORLD_TO_BACKUP"
fi
# Compress files ##########################
local START_TIME=$(date +"%s")
# Compression with incremental (save more space)
tar -z --create --file=$ARCHIVE_PATH --listed-incremental=$BACKUP_DIRECTORY/save.list $WORLD_TO_BACKUP
sync
local END_TIME=$(date +"%s")
##############################################
# Enable world autosaving
exec_cmd "save-on"
# Force world save
exec_cmd "save-all"
# Calculates variables
WORLD_SIZE_BYTES=$(du -b --max-depth=0 $WORLD_TO_BACKUP | awk '{print $1}')
ARCHIVE_SIZE_BYTES=$(du -b $ARCHIVE_PATH | awk '{print $1}')
# Display variables
COMPRESSION_PERCENT=$(( 100 - ($ARCHIVE_SIZE_BYTES * 100 / $WORLD_SIZE_BYTES)))
WORLD_SIZE=$(du -h --max-depth=0 $WORLD_TO_BACKUP | awk '{print $1}')
ARCHIVE_SIZE=$(du -h $ARCHIVE_PATH | awk '{print $1}')
BACKUP_DIRECTORY_SIZE=$(du -h --max-depth=0 $BACKUP_DIRECTORY | awk '{print $1}')
local EXECUTION_TIME=$(($END_TIME - $START_TIME))
# Display ending message ###################
if [[ "$ARCHIVE_SIZE" != "" ]]; then
send_message "Backup finish successfuly !"
send_message_to_admin "Backup finish in $EXECUTION_TIME s, $ARCHIVE_SIZE/$WORLD_SIZE, compression $COMPRESSION_PERCENT%"
send_message_to_admin "Total space used in $BACKUP_DIRECTORY : $BACKUP_DIRECTORY_SIZE"
if $CONSOLE_LOG; then
echo "Backup finish in $EXECUTION_TIME s, $ARCHIVE_SIZE/$WORLD_SIZE, compression $COMPRESSION_PERCENT%"
echo "Total space used in $BACKUP_DIRECTORY : $BACKUP_DIRECTORY_SIZE"
echo "======================================================="
fi
else
send_message "Error in backup process... World not save !"
if $CONSOLE_LOG; then
echo "Error in backup process... World not save !"
echo "======================================================="
fi
fi
}
################################################################
# Restore world #
################################################################
restore () {
local ACTION=$1
if [[ $ACTION == 'restore' ]]; then
echo "Starting restore of $WORLD_TO_BACKUP"
else
echo "Start extracting old backup..."
cd "$BACKUP_DIRECTORY/"
fi
local START_TIME=$(date +"%s")
# Decompress files ##########################
if [[ $ACTION == 'restore' ]]; then
for backup in `ls $BACKUP_DIRECTORY | grep /*.tar`
do
tar --extract --listed-incremental=/dev/null --file $BACKUP_DIRECTORY/$backup
done
else
for backup in `ls | grep /*.tar`
do
tar --extract --listed-incremental=/dev/null --file $backup
done
fi
sync
################################################
local END_TIME=$(date +"%s")
local EXECUTION_TIME=$(($END_TIME - $START_TIME))
if [[ $ACTION == 'restore' ]]; then
echo "Ending restore of world in $EXECUTION_TIME s"
else
echo "Old backup extract in $EXECUTION_TIME s"
cd ../
fi
}
################################################################
# Delete old backup #
################################################################
# To do...
################################################################
# Initialize script #
################################################################
# Save log in file
if $ENABLE_LOG_FILE; then
exec 1>>$LOG_FILE
exec 2>>$LOG_ERROR_FILE
fi
# Create backup directory if not exist
if ! [[ -d $BACKUP_DIRECTORY ]]; then
mkdir $BACKUP_DIRECTORY
fi
# Redirect function
if [[ $1 != '' && $1 == '-restore' ]]; then
restore "restore"
else
backup
fi
Et un screen de mon dossier backupMinecraft ou on peut voir la taille de l'archive (sachant que la première sauvegarde à été lancé manuellement et les autres automatiquement) :
Edit: C'était simplement un problème dans mes variables, le chemin était relatif alors qu'il faut le chemin complet.
Dernière modification par Flashneo (Le 06/07/2020, à 16:16)
Hors ligne
#2 Le 06/07/2020, à 13:13
- kerenoc
Re : [Résolu] Problème crontab execution script
Peut-être mettre "set -x" en début de backup.sh et récupérer les sorties stdout et stderr pour analyser ce qui se passe?
Hors ligne
#3 Le 06/07/2020, à 13:22
- Flashneo
Re : [Résolu] Problème crontab execution script
Pour les sorties stdout et stderr est-ce que la ligne dans le script est bonne :
exec 1>>$LOG_FILE
exec 2>>$LOG_ERROR_FILE
pour le set -x, je n'ai pas de sortie lorsqu'il est exécuté par la crontab, mais j'ai une sortie quand je le lance manuellement.
Dernière modification par Flashneo (Le 06/07/2020, à 13:33)
Hors ligne
#4 Le 06/07/2020, à 14:24
- kamaris
Re : [Résolu] Problème crontab execution script
Il faut mettre les chemins complets des exécutables dans le script, ou définir le path : https://doc.ubuntu-fr.org/cron#autres_considerations
Hors ligne
#5 Le 06/07/2020, à 14:48
- Flashneo
Re : [Résolu] Problème crontab execution script
Je viens d'essayer en définissant le path dans ma crontab comme indiqué dans le lien, mais même après un restart du service ça ne change rien
Du coup j'ai voulu essayé l'autre méthode proposé, mais je n'arrive pas à tomber sur le chemin complet de l'exécutables de "tar", y a t-il un site qui répertorie tous les chemins des commandes ?
Edit : J'ai trouvé pour tar c'est /bin/tar, du coup j'ai remplacé dans le script mais toujours pareil, l'exécution par la crontab ne donne rien
Dernière modification par Flashneo (Le 06/07/2020, à 15:06)
Hors ligne
#6 Le 06/07/2020, à 15:08
- kamaris
Re : [Résolu] Problème crontab execution script
command -v tar
Tu peux remplacer tes noms de commande par
$(command -v nom-de-commande)
dans le script
Hors ligne
#7 Le 06/07/2020, à 15:14
- Flashneo
Re : [Résolu] Problème crontab execution script
Je viens d'essayer et j'ai toujours le même problème
Hors ligne
#8 Le 06/07/2020, à 15:18
- kamaris
Re : [Résolu] Problème crontab execution script
Bah j'ai dit une bêtise, désolé : si tu remplaces les noms de commandes par $(command -v nom-de-commande), ça ne marchera pas mieux, car command -v se base sur le PATH…
Il faut que tu indiques les chemins complets en dur.
Après, peut-être que ça n'est pas (que) ça le problème effectivement, mais c'est souvent le cas.
Hors ligne
#9 Le 06/07/2020, à 15:23
- Flashneo
Re : [Résolu] Problème crontab execution script
Ce que je comprend pas c'est que ça me créer bien des archives à chaque fois mais elles sont toutes vides... Et le "exec 1>> $LOG_FILE" que j'ai mis n'est pas modifier quand c'est cron qui lance le script
J'ai pourtant essayé de mettre les chemins en dure ^^
Dernière modification par Flashneo (Le 06/07/2020, à 15:24)
Hors ligne
#10 Le 06/07/2020, à 15:27
- kerenoc
Re : [Résolu] Problème crontab execution script
Vérifier quel shell est utilisé par crontab. Si c'est /bin/sh il est peut-être plus prudent de mettre une entrée de type "backup.sh 2>&1 >> mon_fichier_log"
Dernière modification par kerenoc (Le 06/07/2020, à 15:27)
Hors ligne
#11 Le 06/07/2020, à 15:33
- kamaris
Re : [Résolu] Problème crontab execution script
Ah mais il y a tous tes chemins définis en relatif en entrée de script aussi, dont WORLD_TO_BACKUP="./world".
Ça ça ne peut pas marcher que lorsque tu lances le script du bon endroit, indépendamment de cron.
Hors ligne
#12 Le 06/07/2020, à 15:36
- Flashneo
Re : [Résolu] Problème crontab execution script
Du coup ça veut dire que je dois mettre les chemins en dur en entrée ?
Hors ligne
#13 Le 06/07/2020, à 15:40
- kamaris
Re : [Résolu] Problème crontab execution script
Pas obligé non : tu dois pouvoir définir
BASEDIR=$(/usr/bin/dirname "$0")
Puis
WORLD_TO_BACKUP="$BASEDIR/world"
À condition que le script soit lui-même au bon endroit, bien entendu !
Dernière modification par kamaris (Le 06/07/2020, à 15:44)
Hors ligne
#14 Le 06/07/2020, à 15:42
- Flashneo
Re : [Résolu] Problème crontab execution script
Ok, j'ai testé avec le chemin complet partout et ça fonctionne très bien
à quoi sert le "$0" ?
Hors ligne
#15 Le 06/07/2020, à 15:47
- kamaris
Re : [Résolu] Problème crontab execution script
C'est le premier (ou l'avant premier) paramètre positionnel, qui contient ici le nom sous lequel le script est appelé.
Cf. man bash
Dernière modification par kamaris (Le 06/07/2020, à 15:48)
Hors ligne
#16 Le 06/07/2020, à 15:53
- Flashneo
Re : [Résolu] Problème crontab execution script
Super, merci je vais essayé ça alors !
Sinon, c'est un autre problème mais j'ai remarqué que si je lance mon script manuellement la première, puis si la seconde fois est lancé par cron l'archive est reconstruite en entier et il n'utilise pas l'incrémentation d'archive...
C'est un problème de droit ?
Hors ligne
#17 Le 06/07/2020, à 15:59
- kamaris
Re : [Résolu] Problème crontab execution script
Tu peux reposter le script que tu lances par cron maintenant, après modifs ?
Hors ligne
#18 Le 06/07/2020, à 16:02
- Flashneo
Re : [Résolu] Problème crontab execution script
Voilà :
#!/bin/bash
################################################################
# #
################################################################
# Configuration ###########################
BACKUP_DIRECTORY="/mnt/library/backupMinecraft"
WORLD_TO_BACKUP="/home/flashneo/minecraft/world"
SCREEN_NAME="serverMinecraft"
ADMIN_PSEUDO="Flashneo"
PREFIX="AutoBackup"
ENABLE_CHAT_MESSAGE=true
ENABLE_ADMIN_MESSAGE=true
CONSOLE_LOG=true
ENABLE_LOG_FILE=true
LOG_FILE="/home/flashneo/minecraft/backup.log"
LOG_ERROR_FILE="/home/flashneo/minecraft/backup.error.log"
###########################################
# Do not modify
DATE_FORMAT="%F_%H%M"
DATE=$(date +$DATE_FORMAT)
ARCHIVE_FILE_NAME=$DATE.tar.gz
ARCHIVE_PATH=$BACKUP_DIRECTORY/$ARCHIVE_FILE_NAME
################################################################
# Minecraft console commands #
################################################################
exec_cmd () {
local COMMAND=$1
if [[ $SCREEN_NAME != "" ]]; then
if screen -ls | grep -q $SCREEN_NAME; then
screen -S $SCREEN_NAME -p 0 -X stuff "$COMMAND$(printf \\r)"
fi
fi
}
send_message () {
if $ENABLE_CHAT_MESSAGE; then
local MESSAGE=$1
exec_cmd "tellraw @a [\"\",{\"text\":\"[\",\"color\":\"white\"},{\"text\":\"$PREFIX\",\"color\":\"dark_gray\"},{\"text\":\"] \",\"color\":\"white\"},{\"text\":\"$MESSAGE\",\"color\":\"gold\"}]"
fi
}
send_message_to_admin () {
if $ENABLE_ADMIN_MESSAGE; then
local MESSAGE=$1
exec_cmd "tellraw $ADMIN_PSEUDO [\"\",{\"text\":\"[\",\"color\":\"white\"},{\"text\":\"$PREFIX\",\"color\":\"dark_gray\"},{\"text\":\"] \",\"color\":\"white\"},{\"text\":\"$MESSAGE\",\"color\":\"gold\"}]"
fi
}
################################################################
# Backup world #
################################################################
backup () {
# Disable world autosaving
exec_cmd "save-off"
send_message "Starting backup of world"
if $CONSOLE_LOG; then
echo "======================================================="
echo "$DATE"
echo "Starting backup of $WORLD_TO_BACKUP"
fi
# Compress files ##########################
local START_TIME=$(date +"%s")
# Compression with incremental (save more space)
tar -z --create --file=$ARCHIVE_PATH --listed-incremental=$BACKUP_DIRECTORY/save.list $WORLD_TO_BACKUP
sync
local END_TIME=$(date +"%s")
##############################################
# Enable world autosaving
exec_cmd "save-on"
# Force world save
exec_cmd "save-all"
# Calcul variables
WORLD_SIZE_BYTES=$(du -b --max-depth=0 $WORLD_TO_BACKUP | awk '{print $1}')
ARCHIVE_SIZE_BYTES=$(du -b $ARCHIVE_PATH | awk '{print $1}')
# Display variables
COMPRESSION_PERCENT=$(( 100 - ($ARCHIVE_SIZE_BYTES * 100 / $WORLD_SIZE_BYTES)))
WORLD_SIZE=$(du -h --max-depth=0 $WORLD_TO_BACKUP | awk '{print $1}')
ARCHIVE_SIZE=$(du -h $ARCHIVE_PATH | awk '{print $1}')
BACKUP_DIRECTORY_SIZE=$(du -h --max-depth=0 $BACKUP_DIRECTORY | awk '{print $1}')
local EXECUTION_TIME=$(($END_TIME - $START_TIME))
# Display ending message ###################
if [[ "$ARCHIVE_SIZE" != "" ]]; then
send_message "Backup finish successfuly !"
send_message_to_admin "Backup finish in $EXECUTION_TIME s, $ARCHIVE_SIZE/$WORLD_SIZE, compression $COMPRESSION_PERCENT%"
send_message_to_admin "Total space used in $BACKUP_DIRECTORY : $BACKUP_DIRECTORY_SIZE"
if $CONSOLE_LOG; then
echo "Backup finish in $EXECUTION_TIME s, $ARCHIVE_SIZE/$WORLD_SIZE, compression $COMPRESSION_PERCENT%"
echo "Total space used in $BACKUP_DIRECTORY : $BACKUP_DIRECTORY_SIZE"
echo "======================================================="
fi
else
send_message "Error in backup process... World not save !"
if $CONSOLE_LOG; then
echo "Error in backup process... World not save !"
echo "======================================================="
fi
fi
}
################################################################
# Restore world #
################################################################
restore () {
local ACTION=$1
if [[ $ACTION == 'restore' ]]; then
echo "Starting restore of $WORLD_TO_BACKUP"
else
echo "Start extracting old backup..."
cd "$BACKUP_DIRECTORY/"
fi
local START_TIME=$(date +"%s")
# Decompress files ##########################
if [[ $ACTION == 'restore' ]]; then
for backup in `ls $BACKUP_DIRECTORY | grep /*.tar`
do
tar --extract --listed-incremental=/dev/null --file $BACKUP_DIRECTORY/$backup
done
else
for backup in `ls | grep /*.tar`
do
tar --extract --listed-incremental=/dev/null --file $backup
done
fi
sync
################################################
local END_TIME=$(date +"%s")
local EXECUTION_TIME=$(($END_TIME - $START_TIME))
if [[ $ACTION == 'restore' ]]; then
echo "Ending restore of world in $EXECUTION_TIME s"
else
echo "Old backup extract in $EXECUTION_TIME s"
cd ../
fi
}
################################################################
# Delete old backup #
################################################################
# To do...
################################################################
# Initialize script #
################################################################
# Save log in file
if $ENABLE_LOG_FILE; then
exec 1>>$LOG_FILE
exec 2>>$LOG_ERROR_FILE
fi
# Create backup directory if not exist
if ! [[ -d $BACKUP_DIRECTORY ]]; then
mkdir $BACKUP_DIRECTORY
fi
# Redirect function
if [[ $1 != '' && $1 == '-restore' ]]; then
restore "restore"
else
backup
fi
J'ai pas encore eu le temps d'ajouter ce que tu m'as dit
Dernière modification par Flashneo (Le 06/07/2020, à 16:03)
Hors ligne
#19 Le 06/07/2020, à 16:08
- kamaris
Re : [Résolu] Problème crontab execution script
Tu es sûr de ton BACKUP_DIRECTORY ?
En #1, c'était
BACKUP_DIRECTORY="./mnt/library/backupMinecraft"
WORLD_TO_BACKUP="./world"
Donc là, est-ce que ça ne devrait pas être
BACKUP_DIRECTORY="/home/flashneo/minecraft/mnt/library/backupMinecraft"
WORLD_TO_BACKUP="/home/flashneo/minecraft/world"
?
Car ce BACKUP_DIRECTORY est justement impliqué dans le caractère incrémental de la sauvegarde (il me semble).
Dernière modification par kamaris (Le 06/07/2020, à 16:11)
Hors ligne
#20 Le 06/07/2020, à 16:12
- Flashneo
Re : [Résolu] Problème crontab execution script
Oui, le script c'est lancé et a bien sauvegarder au bon endroit, après c'est sur un disque dur externe et pour y accéder je tape
cd /mnt/library/backupMinecraft
Et ça peu importe ou je suis ^^
Et oui c'est bien là qu'est sauvegarder le fichier ".list" utiliser par le tar incremental, en plus des archives créés
Hors ligne
#21 Le 06/07/2020, à 16:15
- Flashneo
Re : [Résolu] Problème crontab execution script
J'avais pas remarqué mais en #1 j'ai fait une erreur du coup en mettent le ./ au lieu de juste / devant le chemin
Hors ligne
#22 Le 06/07/2020, à 16:17
- kamaris
Re : [Résolu] Problème crontab execution script
Ok, mais du coup c'est bien avec cette dernière version du script (celle postée en #18) que tu as fait le test de lancer une première sauvegarde manuelle puis une seconde par cron (comme tu dis en #16) ?
Hors ligne
#23 Le 06/07/2020, à 16:24
- Flashneo
Re : [Résolu] Problème crontab execution script
Oui, c'est bien avec cette version du script
Hors ligne
#24 Le 06/07/2020, à 16:30
- kamaris
Re : [Résolu] Problème crontab execution script
Bah je sais pas trop alors, j'utilise pas assez cron et les sauvegardes incrémentales pour y voir bien clair, et j'ai pas trop envie de me lancer dans ce genre de tests en ce moment !
Hors ligne
#25 Le 06/07/2020, à 16:33
- Flashneo
Re : [Résolu] Problème crontab execution script
C'est pas grave, déjà tout fonctionne et j'ai des sauvegardes régulières ça me convient parfaitement !
En tout cas merci pour l'aide, je pense que j'aurais jamais pensé à un truc si bête ^^
Bonne fin de journée !
Hors ligne