Qual é o 'diretório de trabalho' quando o cron executa um trabalho?

170

Eu tenho um script que funciona quando o executo a partir da linha de comando, mas quando o agendamento cronrecebo erros que não conseguem encontrar arquivos ou comandos. Minha pergunta é dupla:

  1. Quando agendar um trabalho cron usando crontab -e, ele usa meu ID de usuário como base para suas permissões? Ou ele usa um ID de usuário cron de algum tipo e suas permissões relacionadas?

  2. Quando um trabalho cron é iniciado, qual é o diretório de trabalho? É o diretório em que especifico o script a ser executado ou um diretório diferente?

Aqui está o meu trabalho cron:

15 7 * * * /home/xxxx/Documents/Scripts/email_ip_script.sh

Aqui está o script real:

vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`"
echo "$vIP_ADDR"
sed "s/IPADDR/$vIP_ADDR/g" template.txt > emailmsg.txt
ssmtp [email protected] < emailmsg.txt

Aqui estão os erros que recebo quando visualizo a mailmensagem produzida por cron:

sed: can't read template.txt: No such file or directory
/home/xxxx/Documents/Scripts/email_ip_script.sh: line 15: ssmtp: command not found

Ele não pode encontrar o template.txtmas reside no mesmo diretório que o script. Ele também não pode ser executado ssmtp, mas eu posso como meu usuário. O que estou faltando para que isso funcione corretamente?

ProfissionalAmador
fonte

Respostas:

158

Adicione cd /home/xxxx/Documents/Scripts/se você deseja que seu trabalho seja executado nesse diretório. Não há razão para que o cron mude para esse diretório específico. Cron executa seus comandos em seu diretório pessoal.

Quanto a ssmtp, pode não estar no seu padrão PATH. O caminho padrão do Cron é dependente da implementação; portanto, verifique sua página de manual, mas ssmtpé provável /usr/sbinque não esteja no seu padrão PATH, apenas no root.

PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
15 7 * * * cd /home/xxxx/Documents/Scripts && ./email_ip_script.sh
Gilles
fonte
@ Giles - Obrigado, teria cronele próprio PATHou posso verificar o meu usuário PATH? Eu configurei o ssmtp para ter o seu próprio usere a wheelpermissão pensando que permitiria a qualquer um usá-lo (incluindo o cron). Se ajuda no Im CENTOS 6.2
ProfessionalAmateur
3
@ ProfessionalProfessionalAmateur Seu problema não é que você não tem permissão para usá-lo ssmtp, mas que seu trabalho cron não encontra nenhum executável chamado ssmtpporque não está no seu PATH. Não existe algo como "seu usuário PATH"; essa é uma configuração por processo, não por usuário. Você pode definir o caminho para todos os seus trabalhos cron colocando uma PATH=…linha no seu crontab.
Gilles
Eu tive que adicionar MAILTO='[email protected] 'também para fazê-lo funcionar junto com a configuração do PATH. Estranho, mas funcionou para mim.
mac
Para ssmtp, pode-se usar; ´which ssmtp´ ...
Fredrick Gauss
@FredrickGauss Make thattype ssmtp
Gilles
20

Se o seu cronjob for um script bash, o seguinte será um CD para o local do seu script (supondo que você esteja usando o caminho absoluto na sua definição cron):

cd "$(dirname "$0")";
Hugo
fonte
14

Para responder à pergunta 1: se você executar crontab -ecomo seu próprio usuário, os trabalhos serão agendados no crontab desse usuário e, portanto, executados com as permissões desse usuário.

Mas você precisa considerar que os trabalhos serão executados em um shell não interativo, o que significa que o $ PATH pode ser diferente daquele que você possui ao executar o script na linha de comando.

É melhor sempre usar caminhos completos em scripts, especialmente se você planeja agendá-los por meio de / cron etc.

Eu também recomendaria o uso de caminhos completos para todos os arquivos para evitar exatamente os problemas que você vê.

Para evitar condições de corrida e outros problemas de segurança, você também deve usar mktemppara garantir que o arquivo que você lê não seja modificado por nada fora do seu script.

Então, eu mudaria o script para algo como:

vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`"
echo "$vIP_ADDR"
mail_msg=`/bin/mktemp`
/bin/sed "s/IPADDR/$vIP_ADDR/g" /home/xxxx/Documents/Scripts/template.txt > $mailmsg
/path/to/ssmtp [email protected] < $mailmsg
/bin/rm $mailmsg
Bram
fonte
7

cronexecuta os trabalhos agendados de cada usuário como esse usuário. Isso deve ser suficiente para concluirmos que ele executa seus scripts em relação ao diretório inicial.

Se você precisar executar a partir de um local diferente, basta usar cdno seu script para ir para esse local.

ssmtpprovavelmente não está no cronPATH padrão (ele está definido para ser muito estreito por design na maioria das plataformas). Você pode especificar o caminho completo para o ssmtpseu script ou definir explicitamente PATH em a) seu arquivo crontab, que estará disponível para todos os seus scripts ou b) em cada script.

D_Bye
fonte
3

Verifique neste tópico como você pode facilmente descobrir o ambiente do cron, é muito menor do que você está acostumado em um shell interativo. O melhor é supor que nada foi definido e defini-lo explicitamente.

jippie
fonte
1

O diretório de trabalho padrão para a cronexecução do trabalho é o diretório inicial, normalmente /home/your-user-name.

Adotando @Kusalananda excelente comentário.

Pessoas inteligentes ajudam os outros
fonte
1
Não. Depende de onde o sistema mantém os diretórios pessoais. /homeestá longe de ser universal.
Kusalananda
1
@Kusalananda O padrão LSB diz /home.
Peterh
1
@peterh Bem, o macOS usa /Userse o histórico do Unices usa /usr, e mesmo no Linux, o diretório inicial de um usuário do sistema pode estar em algum lugar abaixo /varou em outro lugar.
Kusalananda
1
@Kusalananda Está certo.
Peterh
Obrigado, você é a única pessoa que realmente respondeu a esta pergunta :)
OwN
0

Algumas pessoas têm sugerido ou vinculado a ele, mas a melhor maneira de descobrir, já que eu não consigo encontrá-lo nos documentos do homem para minha distribuição, basta adicioná-lo a um cron

* * * * * echo $PATH > /tmp/lolcronjobs

No meu caso, o ubuntu usa como padrão apenas o /usr/bin:/binque causou alguns problemas.

mschuett
fonte