Eu tenho um script bash relativamente simples que funciona muito bem quando invocado diretamente, mas falha quando executado pelo cron. Por que isso falha e como posso fazê-lo funcionar via cron?
#!/bin/bash
apt-get update -y
apt-get upgrade -y
apt-get install boinc-client -y
Depois que o cron tentar executá-lo, uma invocação manual resultará neste erro:
dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.
Mas desde que seja executado manualmente na primeira vez, funciona perfeitamente.
Responder1
A resposta usual para esse tipo de pergunta é que os cron jobs são executados em shells não interativos e sem login, portanto, a maioria dos arquivos de inicialização do shell (tanto os do sistema /etc
quanto os dotfiles pessoais no diretório inicial) não são originados ( lido e executado), porque a maioria dos arquivos de inicialização do shell se aplicam a shells de login (o primeiro shell que você vê quando faz login no computador) ou shells interativos (shells que estão conectados a terminais, sessões ssh ou emuladores de terminal porque um usuário é interagindo com eles através do referido terminal).
Portanto, se você colocar um comando em um cron job que realmente depende de alguma configuração de ambiente (incluindo PATH
alterações) que geralmente acontece em locais como /etc/profile
, /etc/bashrc
, ~/.profile
, ou ~/.bashrc
, essa configuração não acontecerá para um cron job. O formato de arquivo cron permite especificar variáveis de ambiente para seus trabalhos, portanto, você pode querer especificá- lo BASH_ENV
ou ENV
apontá-lo para um script de inicialização do shell para a origem. Consulte a seção "Invocação" da bash(1)
página de manual.
Responder2
Isso não se qualifica como resposta, mas não posso comentar. Sugestões:
acrescente o seguinte ao seu script bash. A última linha registrada na saída do email será o comando com falha.
set -x set -e
- certifique-se de ter o sendmail (instale um pacote fornecido como
postfix
ouesmtp
) - instale um leitor de e-mail (recomendado
mutt
) - garantir que o e-mail chegue até você
- via postfix (pode ser feito automaticamente pelo instalador):
root: my-user-name
adicione/etc/aliases
ou/etc/postfix/aliases
- via cron: adicione
MAILTO="my-user-name"
aocrontab
arquivo apropriado
- via postfix (pode ser feito automaticamente pelo instalador):
- certifique-se de ter o sendmail (instale um pacote fornecido como
Verifique se o script será executado em um ambiente diferente. Especifique o caminho completo para o apt-get (provavelmente não é o culpado, já que se sabe que o apt-get foi encontrado) e execute-o em um console (não terminal) fora do X. (alguns scripts de configuração do dpkg requerem uma sessão X).
- modifique o script para usar caminhos absolutos, ou seja,
/usr/bin/apt-get update -y
(substitua pelo caminho correto) - mude para um console pressionando
ctrl-alt-f1
- mude para usuário root:
sudo -i
- inicie um shell sem login sem um ambiente:
env -i /bin/bash --noprofile --norc
(substitua pelo caminho correto) - execute o script:
/my/full/path/to/cronscript
. Funciona?
- modifique o script para usar caminhos absolutos, ou seja,
O script tem permissão? Você está usando o sistema crontab? (mais uma vez, provavelmente não é o culpado)
- Você declarou que está usando o crontab do sistema, portanto, ignore isso.
O apt-get requer suporte de sessão (consolekit ou systemd). No entanto, este é apenas um tiro no escuro.
- Não sei o suficiente para ajudar.
Responder3
Consegui resolvê-lo com quase nenhuma compreensão do que estava acontecendo. Acontece que mesmo que eu estivesse executando o root crontab, os comandos do apt-get ainda precisavam de um sudo na frente deles. Logicamente eu esperava que isso não fosse necessário, pois o script já estava sendo executado "como root", mas depois que adicionei o sudo... tudo funcionou exatamente como esperado.