O Cron não usa o caminho do usuário cujo crontab é e, em vez disso, possui o seu. Ele pode ser facilmente alterado adicionando-se PATH=/foo/bar
no início do crontab, e a solução alternativa clássica é sempre usar caminhos absolutos para os comandos executados pelo cron, mas onde é definido o PATH padrão do cron?
Criei um crontab com o seguinte conteúdo no meu sistema Arch (cronie 1.5.1-1) e também testei em uma caixa Ubuntu 16.04.3 LTS com os mesmos resultados:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
Que imprimiu:
$ cat fff
/usr/bin:/bin
Mas por que? O caminho padrão do sistema está definido /etc/profile
, mas isso inclui outros diretórios:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
Não há mais nada relevante em /etc/environment
ou /etc/profile.d
, os outros arquivos que eu pensei que poderiam ser lidos pelo cron:
$ grep PATH= /etc/profile.d/* /etc/environment
/etc/profile.d/jre.sh:export PATH=${PATH}:/usr/lib/jvm/default/bin
/etc/profile.d/mozilla-common.sh:export MOZ_PLUGIN_PATH="/usr/lib/mozilla/plugins"
/etc/profile.d/perlbin.sh:[ -d /usr/bin/site_perl ] && PATH=$PATH:/usr/bin/site_perl
/etc/profile.d/perlbin.sh:[ -d /usr/lib/perl5/site_perl/bin ] && PATH=$PATH:/usr/lib/perl5/site_perl/bin
/etc/profile.d/perlbin.sh:[ -d /usr/bin/vendor_perl ] && PATH=$PATH:/usr/bin/vendor_perl
/etc/profile.d/perlbin.sh:[ -d /usr/lib/perl5/vendor_perl/bin ] && PATH=$PATH:/usr/lib/perl5/vendor_perl/bin
/etc/profile.d/perlbin.sh:[ -d /usr/bin/core_perl ] && PATH=$PATH:/usr/bin/core_perl
Também não há nada relevante em nenhum dos arquivos /etc/skel
, sem surpresa, nem está sendo definido em nenhum /etc/cron*
arquivo:
$ grep PATH /etc/cron* /etc/cron*/*
grep: /etc/cron.d: Is a directory
grep: /etc/cron.daily: Is a directory
grep: /etc/cron.hourly: Is a directory
grep: /etc/cron.monthly: Is a directory
grep: /etc/cron.weekly: Is a directory
/etc/cron.d/0hourly:PATH=/sbin:/bin:/usr/sbin:/usr/bin
Então, onde está o PATH padrão do cron para crontabs de usuário sendo definido? É codificado em cron
si mesmo? Ele não lê algum tipo de arquivo de configuração para isso?
cron
olhar/etc/profile
ou se preocupar com qualquer shell em particular. Uma pergunta melhor é por que nãocron
lêPATH
dologin.defs
(no Linux) oulogin.conf
(no * BSD). Suponho que seja, em última análise, um detalhe de implementação./etc/profile
porque ele usa a mesma sintaxe (var=value
) quecron
ela mesma, então seria fácil o suficiente e/etc/profile
é, que eu sei, muito difundido. O que me surpreendeu é que eu não conseguia encontrá-lo definido em nenhum lugar, então parecia que estava codificado. Como é de fato o caso, como Stephen explicou abaixo.zsh
como seu shell interativo não se preocupam com/etc/profile
(que é específico parabash
)profile
arquivos são lidos apenas pelos shells de login. Estes podem, ou podem não ser interativos.strings
em um programa também ajuda a encontrar esses valores codificados.Respostas:
É codificado no código fonte (esse link aponta para o Debian atual
cron
- dada a variedade decron
implementações, é difícil escolher uma, mas outras implementações provavelmente são semelhantes):cron
não lê caminhos padrão de um arquivo de configuração; Imagino que o raciocínio seja o de que ele suporta a especificação de caminhos que já estão sendo usadosPATH=
em qualquer cronjob, portanto não há necessidade de especificar um padrão em outro lugar. (O padrão codificado é usado se nada mais especificou um caminho em uma entrada de trabalho .)fonte
_PATH_DEFPATH_ROOT
define, eu confirmei (usando uma tarefa cron deecho $PATH > /testfile
) após editar o crontab do root usandocrontab -e
no Debian Stretch que o crontab do root também usa_PATH_DEFPATH
, ou seja, "/ usr / bin: / bin", não_PATH_DEFPATH_ROOT
. Isso também é confirmado pelo segundo link do código-fonte nesta resposta (no qual_PATH_DEFPATH_ROOT
não é usado). Não está claro para mim se essa definição órfã é um bug.Adicionando à resposta de Stephen Kitt, existe um arquivo de configuração que define o
PATH
cron no Ubuntu ecron
ignora oPATH
uso do padrão embutido (ouPATH
s definido no próprio crontabs). O arquivo é/etc/environment
.cron
Configuração do PAM da nota :Isso é facilmente verificável. Adicione uma variável para
/etc/environment
, digamosfoo=bar
, executarenv > /tmp/foo
como um cronjob e observe comofoo=bar
aparece na saída.Isso é verdade no Arch Linux, mas no Ubuntu, a base
PATH
está definida/etc/environment
. Arquivos/etc/profile.d
aderidos a um existentePATH
e você pode anexá-lo a~/.pam_environment
. Eu tenho um bug registrado sobre o comportamento de Arch .Infelizmente,
/etc/pam.d/cron
não inclui a leitura de~/.pam_environment
. Estranhamente,/etc/pam.d/atd
não incluir esse arquivo:... mas os comandos executados via
at
aparentemente herdam o ambiente disponível ao criar oat
trabalho (por exemplo,env -i /usr/bin/at ...
parece executar trabalhos com um ambiente muito limpo).Alterar
/etc/pam.d/cron
teruser_readenv=1
parece não causar problemas, e as variáveis~/.pam_environment
começaram a aparecer bem (excetoPATH
, é claro).Ao todo, definir variáveis de ambiente para o cron parece ser um negócio confuso. O melhor lugar parece estar na própria especificação do trabalho, apenas porque você não sabe quais variáveis de ambiente herdadas o cron pode decidir ignorar (sem ler a fonte).
fonte
at
trabalhos, se você despejar umat
trabalho, verá que ele define explicitamente o ambiente para corresponder ao ambiente quando o trabalho foi criado.