Onde o PATH do cron está configurado?

31

O Cron não usa o caminho do usuário cujo crontab ele é e, em vez disso, tem o seu próprio. Ele pode ser facilmente alterado adicionando PATH=/foo/bar no início do crontab, e a solução clássica é sempre usar caminhos absolutos para comandos executados pelo cron, mas onde o PATH padrão do cron está definido?

Eu criei um crontab com o seguinte conteúdo no meu sistema Arch (cronie 1.5.1-1) e também testado em uma caixa LTS do Ubuntu 16.04.3 com os mesmos resultados:

$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff

impresso:

$ cat fff
/usr/bin:/bin

Mas por quê? O caminho padrão do sistema é definido em /etc/profile , mas isso inclui outros diretórios:

$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"

Não há nada mais relevante em /etc/environment ou /etc/profile.d , os outros arquivos que achei 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 em /etc/skel , não é surpresa, nem está sendo definido em nenhum arquivo /etc/cron* :

$ 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 default do cron para o usuário crontabs ser definido? É codificado em cron ? Não lê algum tipo de arquivo de configuração para isso?

    
por terdon 31.10.2017 / 13:51

2 respostas

45

Ele está codificado no código-fonte (esse link aponta para o Debian atual cron - dada a variedade de cron implementações, é difícil escolher uma, mas outras implementações são provavelmente similares):

#ifndef _PATH_DEFPATH
# define _PATH_DEFPATH "/usr/bin:/bin"
#endif

#ifndef _PATH_DEFPATH_ROOT
# define _PATH_DEFPATH_ROOT "/usr/sbin:/usr/bin:/sbin:/bin"
#endif

cron não lê os caminhos padrão de um arquivo de configuração; Eu imagino o raciocínio de que ele suporta a especificação de caminhos que já usam PATH= em qualquer cron job, portanto, não é necessário especificar um padrão em outro lugar. (O padrão hard-coded é usado se nada mais especificasse um caminho em uma entrada de trabalho .

    
por 31.10.2017 / 13:55
8

Somando-se à resposta de Stephen Kitt, há um arquivo de configuração que define PATH para o cron no Ubuntu, e cron ignora que PATH usa o padrão embutido em código (ou PATH s definido nos próprios crontabs). O arquivo é /etc/environment . Observe a configuração do PAM de cron :

$ cat /etc/pam.d/cron
...   
# Read environment variables from pam_env's default files, /etc/environment
# and /etc/security/pam_env.conf.
session       required   pam_env.so

# In addition, read system locale information
session       required   pam_env.so envfile=/etc/default/locale
...

Isso é facilmente verificável. Adicione uma variável a /etc/environment , digamos foo=bar , execute env > /tmp/foo como um cronjob e observe como foo=bar aparece na saída.

But why? The default system-wide path is set in /etc/profile, but that includes other directories:

$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"

Isso é verdade no Arch Linux, mas no Ubuntu, a base PATH está definida em /etc/environment . Os arquivos em /etc/profile.d são anexados a um PATH existente e você pode anexá-lo em ~/.pam_environment . Eu tenho um um bug arquivado sobre o comportamento do Arch .

Infelizmente, /etc/pam.d/cron não inclui a leitura de ~/.pam_environment . Estranhamente, /etc/pam.d/atd inclui esse arquivo:

$ cat /etc/pam.d/atd
#
# The PAM configuration file for the at daemon
#

@include common-auth
@include common-account
session    required   pam_loginuid.so
@include common-session-noninteractive
session    required   pam_limits.so
session    required   pam_env.so user_readenv=1

... mas os comandos executados via at aparentemente herdam o ambiente disponível ao criar o trabalho at (por exemplo, env -i /usr/bin/at ... parece executar trabalhos com um ambiente muito limpo).

A alteração de /etc/pam.d/cron para ter user_readenv=1 parece não causar problemas, e as variáveis em ~/.pam_environment começaram a aparecer bem (com exceção de PATH , é claro).

Tudo dito, a configuração de 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, mesmo porque você não sabe quais variáveis de ambiente herdadas o cron pode decidir ignorar (sem ler a origem).

    
por 01.11.2017 / 07:46

Tags