Je suis un débutant dans les scripts Shell. J'ai écrit un script Shell pour effectuer une sauvegarde incrémentielle de la base de données MySQL. Le script est au format exécutable et s'exécute correctement lorsqu'il est exécuté manuellement, mais échoue lorsqu'il est exécuté via crontab.
L'entrée Crontab est comme ceci:
*/1 * * * * /home/db-backup/mysqlbackup.sh
Vous trouverez ci-dessous le code de script Shell -
#!/bin/sh
MyUSER="root" # USERNAME
MyPASS="password" # PASSWORD
MyHOST="localhost" # Hostname
Password="" #Linux Password
MYSQL="$(which mysql)"
if [ -z "$MYSQL" ]; then
echo "Error: MYSQL not found"
exit 1
fi
MYSQLADMIN="$(which mysqladmin)"
if [ -z "$MYSQLADMIN" ]; then
echo "Error: MYSQLADMIN not found"
exit 1
fi
CHOWN="$(which chown)"
if [ -z "$CHOWN" ]; then
echo "Error: CHOWN not found"
exit 1
fi
CHMOD="$(which chmod)"
if [ -z "$CHMOD" ]; then
echo "Error: CHMOD not found"
exit 1
fi
GZIP="$(which gzip)"
if [ -z "$GZIP" ]; then
echo "Error: GZIP not found"
exit 1
fi
CP="$(which cp)"
if [ -z "$CP" ]; then
echo "Error: CP not found"
exit 1
fi
MV="$(which mv)"
if [ -z "$MV" ]; then
echo "Error: MV not found"
exit 1
fi
RM="$(which rm)"
if [ -z "$RM" ]; then
echo "Error: RM not found"
exit 1
fi
RSYNC="$(which rsync)"
if [ -z "$RSYNC" ]; then
echo "Error: RSYNC not found"
exit 1
fi
MYSQLBINLOG="$(which mysqlbinlog)"
if [ -z "$MYSQLBINLOG" ]; then
echo "Error: MYSQLBINLOG not found"
exit 1
fi
# Get data in dd-mm-yyyy format
NOW="$(date +"%d-%m-%Y-%T")"
DEST="/home/db-backup"
mkdir $DEST/Increment_backup.$NOW
LATEST=$DEST/Increment_backup.$NOW
$MYSQLADMIN -u$MyUSER -p$MyPASS flush-logs
newestlog=`ls -d /usr/local/mysql/data/mysql-bin.?????? | sed 's/^.*\.//' | sort -g | tail -n 1`
echo $newestlog
for file in `ls /usr/local/mysql/data/mysql-bin.??????`
do
if [ "/usr/local/mysql/data/mysql-bin.$newestlog" != "$file" ]; then
echo $file
$CP "$file" $LATEST
fi
done
for file1 in `ls $LATEST/mysql-bin.??????`
do
$MYSQLBINLOG $file1>$file1.$NOW.sql
$GZIP -9 "$file1.$NOW.sql"
$RM "$file1"
done
$RSYNC -avz $LATEST /home/rsync-back
Quand j'ai fait $ echo PATH, j'ai eu ceci
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/mysql/bin:/opt/Android-sdk-linux/tools:/opt/Android-sdk-linux/platform-tools:~/usr/lib/jvm/jdk-6/bin
Le problème est probablement que votre $ PATH est différent dans l'environnement manuel de celui sous lequel crontab est exécuté. Par conséquent, which
ne peut pas trouver vos exécutables. Pour résoudre ce problème, commencez par imprimer votre chemin dans l'environnement manuel (echo $PATH
), puis configurez manuellement PATH en haut du script que vous exécutez dans crontab. Ou tout simplement faire référence aux programmes par leur chemin complet.
Edit: Ajoutez ceci près du haut de votre script, avant tous les appels which
:
export PATH="/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/mysql/bin:/opt/Android-sdk-linux/tools:/opt/Android-sdk-linux/platform-tools:~/usr/lib/jvm/jdk-6/bin"
Une autre méthode plus générique consiste à faire exécuter par cron le processus de connexion bash de l'utilisateur. En plus du PATH, cela récupérera également les paramètres LD_LIBRARY_PATH, LANG, les autres variables d’environnement, etc.
34 12 * * * bash -l /home/db-backup/mysqlbackup.sh
Mon problème était que je définisse le travail cron dans /etc/cron.d (Centos 7). Il semble que, dans ce cas, je dois spécifier l'utilisateur qui exécute le script, contrairement à la saisie d'un cronjob au niveau de l'utilisateur.
Tout ce que je devais faire était
*/1 * * * * root Perl /path/to/my/script.sh
*/5 * * * * root php /path/to/my/script.php
Où "root" indique que j'exécute le script en tant que root . Vous devez également vous assurer que les éléments suivants sont définis en haut du fichier. Vos chemins peuvent être différents. Si vous n'êtes pas sûr, essayez la commande "quel Perl", "quel php".
Shell=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
Importez simplement votre profil d'utilisateur au début du script.
c'est à dire.:
. /home/user/.profile