Normalmente, tenho vários problemas com a forma como o cron executa scripts, pois eles normalmente não têm a configuração do meu ambiente. Existe uma maneira de chamar bash (?) Da mesma forma que o cron faz para que eu possa testar scripts antes de instalá-los?
253
Respostas:
Adicione isso ao seu crontab (temporariamente):
Após a execução, faça o seguinte:
Isso pressupõe que seu cron execute / bin / sh, que é o padrão, independentemente do shell padrão do usuário.
fonte
env -
cat ~ / cronenv` / bin / sh` deve ser escrita como trabalho cron também? por favor, dê um exemploO Cron fornece apenas este ambiente por padrão:
HOME
diretório inicial do usuárioLOGNAME
login do usuárioPATH=/usr/bin:/usr/sbin
SHELL=/usr/bin/sh
Se você precisar de mais, poderá gerar um script no qual define seu ambiente antes da tabela de agendamento no crontab.
fonte
.
geralmente não fazPATH
mais parte , por razões de segurança .Duas abordagens:
Exporte o cron cron e faça a origem:
Adicionar
ao seu crontab, deixe-o funcionar uma vez, desligue-o novamente e depois execute-o
E agora você está dentro de uma
sh
sessão que possui o ambiente do cronTraga seu ambiente para o cron
Você pode pular o exercício acima e fazer um
. ~/.profile
na frente do seu trabalho cron, por exemploUsar tela
As duas soluções acima ainda falham, pois fornecem um ambiente conectado a uma sessão X em execução, com acesso a
dbus
etc. Por exemplo, no Ubuntu, onmcli
(Network Manager) funcionará nas duas abordagens acima, mas ainda falha no cron.Adicione a linha acima ao cron, deixe executar uma vez, desligue-o novamente. Conecte-se à sua sessão de tela (tela -r). Se você estiver verificando se a sessão da tela foi criada (com
ps
), esteja ciente de que às vezes estão em maiúsculas (por exemplops | grep SCREEN
)Agora mesmo
nmcli
e similar irá falhar.fonte
Você pode correr:
Isso executará seu_command com ambiente vazio.
fonte
env - HOME="$HOME" LOGNAME="$USER" PATH="/usr/bin:/bin" SHELL="$(which sh)" command arguments
o que parece fazer o truqueDependendo do shell da conta
ou
De http://matthew.mceachen.us/blog/howto-simulate-the-cron-environment-1018.html
fonte
Respondendo seis anos depois: o problema de incompatibilidade de ambiente é um dos problemas resolvidos pelos
systemd
"temporizadores" como uma substituição do cron. Se você executa o "serviço" systemd da CLI ou via cron, ele recebe exatamente o mesmo ambiente, evitando o problema de incompatibilidade de ambiente.O problema mais comum que causa falha nos trabalhos do cron quando passam manualmente é o padrão restritivo
$PATH
definido pelo cron, que é o Ubuntu 16.04:Por outro lado, o padrão
$PATH
definidosystemd
no Ubuntu 16.04 é:Portanto, já existe uma chance melhor de que um timer do systemd encontre um binário sem mais problemas.
A desvantagem dos timers do systemd é que há um pouco mais de tempo para configurá-los. Você primeiro cria um arquivo de "serviço" para definir o que deseja executar e um arquivo de "cronômetro" para definir o agendamento para execução e, finalmente, "ativar" o cronômetro para ativá-lo.
fonte
Crie um trabalho cron que execute env e redirecione stdout para um arquivo. Use o arquivo ao lado de "env -" para criar o mesmo ambiente que um trabalho cron.
fonte
Não esqueça que, como o pai do cron é init, ele executa programas sem um terminal de controle. Você pode simular isso com uma ferramenta como esta:
http://libslack.org/daemon/
fonte
Por padrão,
cron
executa seus trabalhos usando qualquer que seja a ideia do seu sistemash
. Este poderia ser o escudo real Bourne oudash
,ash
,ksh
oubash
(ou outra) para simbolicamentesh
(e, como resultado que funciona no modo de POSIX).A melhor coisa a fazer é garantir que seus scripts tenham o que eles precisam e supor que nada lhes seja fornecido. Portanto, você deve usar especificações completas do diretório e definir variáveis de ambiente como
$PATH
você.fonte
0 0 * * 1 /path/to/executable >/dev/null 2>&1
e, em "executável", eu definiria valores para$PATH
etc., e usaria especificações de diretório completas para arquivos de entrada e saída, etc. Por exemplo:/path/to/do_something /another/path/input_file /another/path/to/output_file
Outra maneira simples que eu encontrei (mas pode estar sujeito a erros, ainda estou testando) é fonte dos arquivos de perfil do usuário antes do seu comando.
Editando um script /etc/cron.d/:
Transformaria em:
Sujo, mas fez o trabalho por mim. Existe uma maneira de simular um login? Apenas um comando que você poderia executar?
bash --login
não funcionou. Parece que seria o melhor caminho a percorrer.EDIT: Esta parece ser uma solução sólida: http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/
fonte
A resposta aceita fornece uma maneira de executar um script com o ambiente que o cron usaria. Como outros apontaram, esse não é o único critério necessário para depurar tarefas cron.
De fato, o cron também usa um terminal não interativo, sem uma entrada anexada, etc.
Se isso ajudar, eu escrevi um script que permite a execução indolor de um comando / script, como seria executado pelo cron. Invoque-o com seu comando / script como primeiro argumento e você será bom.
Este script também está hospedado (e possivelmente atualizado) no Github .
fonte
A resposta https://stackoverflow.com/a/2546509/5593430 mostra como obter o ambiente cron e usá-lo para o seu script. Mas esteja ciente de que o ambiente pode diferir dependendo do arquivo crontab que você usa. Criei três entradas cron diferentes para salvar o ambiente via
env > log
. Estes são os resultados em um Amazon Linux 4.4.35-33.55.amzn1.x86_64.1. Global / etc / crontab com usuário root
2. Usuário crontab de root (
crontab -e
)3. Script em /etc/cron.hourly/
Mais importante ainda
PATH
,PWD
eHOME
diferem. Certifique-se de configurá-los em seus scripts cron para confiar em um ambiente estável.fonte
Eu não acredito que exista; a única maneira que sei testar um trabalho cron é configurá-lo para executar um ou dois minutos no futuro e aguardar.
fonte