web-dev-qa-db-ja.com

Bashスクリプトは手動で実行されますが、crontabで失敗します

私はシェルスクリプトの初心者です。 MySQLデータベースの増分バックアップを行うシェルスクリプトを作成しました。スクリプトは実行可能形式であり、手動で実行すると正常に実行されますが、crontabを介して実行すると失敗します。
Crontabエントリは次のようになります:*/1 * * * * /home/db-backup/mysqlbackup.sh
以下はシェルスクリプトコードです-

 #!/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
  • まず、crontabでスケジュールされている場合、エラーは表示されません。スクリプトが実行されているかどうかを知るにはどうすればよいですか?
  • 次に、crontabでシェルスクリプトを実行する正しい方法は何ですか。
  • 一部のブログは、環境変数の変更を提案しています。何が最善の解決策でしょう
2
Rudra

Crontabから実行されているスクリプトには、通常許可されているのと同じ環境変数が常にあるとは限りません...これを行う:

変化する

 #!/bin/sh

 #!/bin/sh -x

-xを使用すると、PATHを手動で設定し、他のすべてが失敗した場合は/ etc/profileを開始することもできます。

#!/bin/sh -x
PATH=/bin:/sbin:/usr/bin:/usr/sbin
/bin/sh /etc/profile
2
David Houde

スクリプトでデータベースクエリを使用する場合は常に、パスをエクスポートする必要があります。次に、Oracleデータベースのエクスポートを示します。

Oracle_HOME=/u01/app/Oracle/product/11.2.0/db_1
LD_LIBRARY_PATH=$Oracle_HOME/lib
PATH=$Oracle_HOME/bin:$PATH

export PATH
export Oracle_HOME
export Oracle_SID
export LD_LIBRARY_PATH
0
haroon

シェルの/ bin/shバージョンは、$(...)構成を好みません。最善の策は、次のいずれかを実行することです。
1。シバン行を#!/ bin/bashに変更します
2。 crontabコマンドを*/1 * * * */bin/bash /home/db-backup/mysqlbackup.shに変更します
3。 1と2の両方。

0
John

パスと変数をエクスポートしてみてください。crontabsパスで指定する必要があります。実行方法は問題ありません。StackOとserverfaultには、この問題の答えを見つけることができる投稿がたくさんあります。

0
APZ

迅速なトラブルシューティングを行うには、出力ファイルにエコーをスクリプトに自由に振りかけます。一番上に置くように:

#!/bin/bash
LOGFILE=/tmp/myoutput.log
echo "Starting" > $LOGFILE

等々。次に、スクリプトが実行されているはずの出力ファイルを確認し、おそらくどこで失敗しているかを確認できます。出力がまったくない場合、まだ実行されていない可能性がありますが、これはまだ決定されていません。その後、さらにトラブルシューティングを行うことができます。

0
lsd

短い表現のソリューション:/ etc/crontabファイルのHOME = /ディレクティブをコメント化

今説明:

私のmysqlバックアップスクリプト(bin-logsをフラッシュする)はインタラクティブにうまく機能しましたが、cronの場合は失敗したため、このトピックが見つかりました。しかし、私の設定がRudraの設定と少し異なるため、根本的な原因と解決策も発生しましたが、私と同じ設定を持つ他の人のために、ここに投稿させてください。

わかりました。Rudraのセットアップとの違いは、スクリプトでmysqladminにユーザー名とパスワードを渡さないことです。代わりに、「6.1.2.1。 MySQLのドキュメント( http://dev.mysql.com/doc/refman/5.5/en/password-security-user.html )の「パスワードセキュリティのエンドユーザーガイドライン」、つまり[クライアント]ルートの〜/ .my.cnfファイルのセクション。

Linuxは、〜をHOME環境変数の値に解決します。 cronデーモン(man 5によるcrontabによる)「いくつかの環境変数は、cron(8)デーモンによって自動的に設定されます。シェルは/ bin/shに設定され、LOGNAMEおよびHOMEはcrontabの所有者の/ etc/passwd行から設定されます。 HOMEとShellはcrontabの設定によって上書きされる可能性があります」

したがって、この設定では、「mysqladmin flush-logs」はコマンドラインパラメータとしてパスワードを渡さなくても問題なく機能するはずですが、そうではありませんでした。この理由は、(何らかの理由で)デフォルトの/ etc/crontabファイル(少なくともCenOS 6.2では)にHOME = /ディレクティブがあり、manで説明されている1つのセットアップを上書きするためです。

/ etc/crontabでコメントしてください。

乾杯、ローマ。

0
Arregator

スクリプトがcronから実行されるときに、必要な環境変数が設定されていない可能性があります。試してください:

*/1 * * * * . /etc/profile; /home/db-backup/mysqlbackup.sh >>/tmp/mysqlbackup.log 2>&1

つまり、実際のバックアップの前に、デフォルトのプロファイルスクリプトを実行して、最初に環境をセットアップします。さらに、最後にSTDOUTおよびSTDERRがログファイルにリダイレクトされます。

/ var/log/cronまたは同様のものを探します。 * nixフレーバーによっては、ログが.../messagesまたは.../syslogにある場合もあります。 cronin /etc/syslog.confの正確な構成を探します。

うまくいけば、これが役立ちます:-)

0
grassroot

AIX 7.1のcrontabでも同じ問題が発生しました。

そのため、代わりにコマンド/bin/shをプロファイルシェルに置き換えました。また、Shell file.shコマンドの最初の行に. ~/.profileを追加しました。その後、コマンドは正常に機能しました。

これは私が使用したcrontabの行です。

mm hh * * * d . ~/.profile;/Directory/Command.sh > /LOG/logfile_command.log.`date | awk '{print $3$2$6}'` 2>&1

ここで、mm:分、hh:時間、d:日(0-6)

0
echumbes57