Executar script em um shell não interativo?

17

Eu tenho um trabalho cron que está executando um script. Quando executo o script por meio de um shell interativo (ssh'ed to bash), ele funciona bem. Quando o script é executado via cron, ele falha.

Meu palpite é que ele está usando algumas das variáveis ​​ambientais definidas no shell interativo. Vou solucionar o script e removê-lo.

Depois de fazer as alterações, sei que poderia enfileirar o script no cron para executá-lo normalmente, mas existe uma maneira de executar o script na linha de comando, mas diga-o para executar como faria no cron - ou seja, em um ambiente não interativo?

cwd
fonte
Relacionado e, portanto, possivelmente útil: "Como obter um ambiente limpo em um shell ksh?" veja especialmente a resposta do @Gilles sobre unset.
sr_
1
No link do @ sr_, procurei enve você pode tentar env -i ./my-script.sh. Além disso, você está recebendo uma mensagem de erro?
Kevin
Qual implementação de cron você está usando?
rzcietrzewiacz 03/11
@ Kevin - eu vou votar se você responder com ele.
Cwd

Respostas:

12

As principais diferenças entre executar um comando do cron e executar na linha de comando são:

  • o cron provavelmente está usando um shell diferente (geralmente /bin/sh);
  • o cron está definitivamente rodando em um ambiente pequeno (que depende da implementação do cron, portanto verifique a página cron(8)ou crontab(5)man; geralmente há apenas HOME, talvez SHELL, talvez LOGNAME, talvez USER, e um pequeno PATH);
  • o cron trata o %personagem especialmente (ele se transforma em uma nova linha);
  • os trabalhos cron são executados sem um terminal ou ambiente gráfico.

A chamada a seguir executará o snippet do shell praticamente como se tivesse sido chamado do cron. Presumo que o trecho não contenha os caracteres 'ou %.

env - HOME="$HOME" USER="$USER" PATH=/usr/bin:/bin /bin/sh -c 'shell snippet' </dev/null >job.log 2>&1

Consulte também a execução de um script sh a partir do cron , o que pode ajudar a resolver seu problema.

Gilles 'SO- parar de ser mau'
fonte
Oi @Giles - pensei em alguma coisa - rodar um script sudo -u user /path/to/scripttambém seria uma maneira de executá-lo sem nenhuma variável definida?
Cwd
@cwd Não, geralmente não. sudolimpa algumas variáveis ​​e define outras para um valor conhecido, mas isso depende de como está configurado. Geralmente, é configurado para manter as configurações de localidade e TERM, por exemplo.
Gilles 'SO- stop be evil'
2

No link do @ sr_ ( como obter um ambiente limpo em um shell ksh? ), Procurei o env e você pode tentar o seguinte:

env -i ./my-script.sh
Kevin
fonte
Isso funcionou bem para mim, embora a resposta do @Gilles também seja muito boa.
Cwd
@ CWD: Não funciona para mim: echo -e '#!/bin/bash -i\necho interactive $-' > ~/test.sh && chmod +x ~/test.sh && env -i ~/test.shsaídas interactive himB.
Alix Axel
1

Eu sugiro que você use caminhos absolutos para seus scripts ao colocá-lo no cron e em outros lugares e para todo e qualquer comando linux usado nele, declare-os melhor como variáveis ​​e use-os!

Gaumire
fonte
sim. mas é claro.
Cwd
0

O Cron não usa necessariamente o mesmo shell que você está usando. Verifica:

cat /etc/crontab |grep SHELL

Para determinar o shell e tentar executar o seu script lá - ele funciona? Essa é uma causa comum de problemas para muitas pessoas que adicionam scripts ao cron.

Se este for o problema - você pode adicionar "bash" ao início do seu script no cron para forçar a execução do script no bash. Se isso não resolver o problema, avise-me e aprofundarei um pouco mais.

Matt
fonte
0

Se você deseja ignorar algumas perguntas interativas fornecidas por algum script, tente:

yes | your_command

Ou, yes "n"se você quiser, não todas as perguntas.

Comando:

yes - seja repetitivamente afirmativo, sim produz palavrões ou, por padrão, 'y', para sempre.

kenorb
fonte
0

Para executar seu script em um shell não interativo (sem considerar os detalhes de cron), você pode fazer isso via ssh.

Teste se você realmente acaba em um shell não interativo:

> ssh someuser@somehost tty
not a tty

Execute o script em um shell não interativo:

> ssh someuser@somehost /tmp/myscript.sh
dokaspar
fonte