it-swarm.com.de

Das Bash-Skript wird manuell ausgeführt, schlägt jedoch bei Crontab fehl

Ich bin ein Neuling beim Shell-Scripting. Ich habe ein Shell-Skript geschrieben, um eine inkrementelle Sicherung der MySQL-Datenbank durchzuführen. Das Skript ist im ausführbaren Format und wird erfolgreich ausgeführt, wenn es manuell ausgeführt wird, schlägt jedoch fehl, wenn es über Crontab ausgeführt wird. 

Crontab-Eintrag ist wie folgt:

*/1 * * * * /home/db-backup/mysqlbackup.sh

Unten ist der Shell-Skriptcode -

#!/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
  • Zunächst einmal, wenn auf Crontab geplant, werden keine Fehler angezeigt. Wie erfahre ich, ob das Skript läuft oder nicht?
  • Zweitens: Was ist der richtige Weg, um das Shell-Skript in einer Crontab auszuführen. In einigen Blogs wird vorgeschlagen, die Umgebungsvariablen zu ändern. Was wäre die beste Lösung

Als ich $ echo PATH gemacht habe, habe ich das verstanden 

/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
13
Rudra

Das Problem ist wahrscheinlich, dass sich $ PATH in der manuellen Umgebung von dem unterscheidet, unter dem Crontab ausgeführt wird. Daher kann which Ihre ausführbaren Dateien nicht finden. Um dies zu beheben, drucken Sie zuerst Ihren Pfad in der manuellen Umgebung (echo $PATH) und richten Sie dann PATH am oberen Rand des Skripts ein, das Sie in crontab ausführen. Oder beziehen Sie sich einfach auf die Programme mit ihrem vollständigen Pfad.

Bearbeiten: Fügen Sie dies am oberen Rand Ihres Skripts ein, bevor alle which-Aufrufe aufgerufen werden:

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"
15
amaurea

Eine weitere allgemeinere Methode besteht darin, dass cron den Bash-Anmeldeprozess des Benutzers ausführt. Zusätzlich zum PATH werden hier auch alle LD_LIBRARY_PATH-, LANG-Einstellungen, andere Umgebungsvariablen usw. abgerufen. Codieren Sie dazu Ihren Crontab-Eintrag wie folgt:

34  12  * * *   bash -l /home/db-backup/mysqlbackup.sh
11
JimR

Mein Problem war, dass ich den Cron-Job in /etc/cron.d (Centos 7) eingestellt habe. Es scheint, dass ich dabei den Benutzer angeben muss, der das Skript ausführt, anders als wenn ein Cronjob auf Benutzerebene eingegeben wird. 

Alles was ich tun musste, war 

*/1 * * * * root Perl /path/to/my/script.sh
*/5 * * * * root php /path/to/my/script.php

"Root" gibt an, dass das Skript als root ausgeführt wird. Außerdem müssen Sie sicherstellen, dass die folgenden Elemente oben in der Datei definiert sind. Deine Wege könnten anders sein. Wenn Sie sich nicht sicher sind, versuchen Sie den Befehl "which perl", "which php".

Shell=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
4
blokeish

Importieren Sie einfach Ihr Benutzerprofil am Anfang des Skripts.

d.h .:

. /home/user/.profile
1