O script Bash é executado manualmente, mas falha no crontab

2

Sou novato em scripts de shell. Eu escrevi um shell script para fazer backup incremental do banco de dados MySQL. O script está no formato executável e é executado com sucesso quando executado manualmente, mas falha quando executado através do crontab.
A entrada do Crontab é assim: * / 1 * * * * /home/db-backup/mysqlbackup.sh
Abaixo está o código do script de 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
  • Primeiro de tudo, quando agendado no crontab, ele não está mostrando nenhum erro. Como posso saber se o script está sendo executado ou não?
  • Em segundo lugar, qual é a maneira correta de executar o script de shell em um crontab.
  • Alguns blogs sugerem mudanças nas variáveis de ambiente. Qual seria a melhor solução
por Rudra 30.01.2013 / 20:39

8 respostas

2

Os scripts que estão sendo executados a partir do crontab nem sempre têm as mesmas variáveis ambientais que você normalmente toma como garantidos ... Faça isso:

Alterar

 #!/bin/sh

para

 #!/bin/sh -x

com -x, você pode tentar configurar o PATH manualmente, e até mesmo iniciar o / etc / profile se tudo mais falhar.

#!/bin/sh -x
PATH=/bin:/sbin:/usr/bin:/usr/sbin
/bin/sh /etc/profile
    
por 30.01.2013 / 21:08
0

A versão / bin / sh do shell não gosta da construção $ (...). Sua melhor aposta é fazer um dos seguintes: 1. Mude a linha shebang para #! / Bin / bash
2. Mude o comando crontab para * / 1 * * * * / bin / bash /home/db-backup/mysqlbackup.sh
3. Ambos 1 e 2.

    
por 30.01.2013 / 20:46
0

tente exportar caminhos e variáveis, em caminhos crontabs tem que ser especificado, a maneira que você está executando está bem, há um monte de mensagens no StackO e serverfault onde você pode encontrar resposta para este problema

    
por 30.01.2013 / 20:47
0

Para uma rápida solução de problemas, espalhe seu script com eco em um arquivo de saída. Como colocar um no topo:

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

e assim por diante. Então você pode olhar para o arquivo de saída após o script ter sido executado e, talvez, ver onde ele está falhando. Se não houver saída alguma, é possível que ela nem esteja sendo executada, o que ainda não determinamos. Então você pode solucionar mais.

    
por 30.01.2013 / 21:29
0

As variáveis de ambiente necessárias provavelmente não serão definidas quando o script for executado a partir do cron. Experimente:

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

significa que primeiro configure o ambiente executando o script de perfil padrão antes do backup real. Além disso, no final, há o redirecionamento de STDOUT e STDERR para um arquivo de log.

Procure / var / log / cron ou similar. Dependendo do seu sabor * nix, o log também pode estar em ... / messages ou ... / syslog. Procure cron em /etc/syslog.conf configuração exata.

Espero que isso ajude: -)

    
por 30.01.2013 / 21:44
0

Solução de texto curto: comente HOME = / directive no seu arquivo / etc / crontab

Agora explique:

Eu encontrei este tópico porque meu script de backup mysql, liberando bin-logs, funcionou muito bem interativamente, mas falhou quando o cron. Mas ocorreu que minha configuração foi um pouco diferente da de Rudra, então a causa raiz e a solução também, mas ainda deixe-me postar aqui para outras pessoas com a mesma configuração que eu.

Ok, minha diferença da configuração do Rudra é que eu não passo nome de usuário e senha para mysqladmin no script. Em vez disso, configuro como sugerido em “6.1.2.1. Diretrizes para o usuário final para segurança de senha ”da documentação do MySQL ( link ) ou seja, na seção [cliente] do arquivo ~ / .my.cnf do root.

O Linux resolve resolve ~ nos valores da variável de ambiente HOME. daemon cron (como por homem 5 crontab) “Várias variáveis de ambiente são configuradas automaticamente pelo daemon cron (8). SHELL é definido como / bin / sh, e LOGNAME e HOME são definidos a partir da linha / etc / passwd do proprietário do crontab. HOME e SHELL podem ser substituídas por configurações no crontab ”

Então, com essa configuração “mysqladmin flush-logs” deve funcionar muito bem sem passar a senha como um parâmetro de linha de comando, mas NÃO. E a razão para isto ocorreu que (por alguma razão) o arquivo padrão / etc / crontab (pelo menos no CenOS 6.2) tem uma diretiva HOME = /, sobrescrevendo a configuração como descrito em man.

Então, comente em seu / etc / crontab e veja que ajuda você!

Felicidades, Romano.

    
por 19.12.2013 / 18:52
0

Eu tive o mesmo problema com o crontab no AIX 7.1.

Para isso, substitui o comando /bin/sh pelo shell do perfil. Além disso, no shell de comando file.sh adicionado . ~/.profile na primeira linha. Depois disso, o comando funcionou bem.

Esta é a linha no crontab que eu usei:

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

em que mm: minutos, hh: hora, d: dia (0-6)

    
por 03.08.2016 / 02:39
0

Sempre que você usar a consulta do DataBase em um script, precisará exportar o caminho. A seguir, a exportação do banco de dados 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
    
por 12.08.2016 / 15:42

Tags