Cron no usa la ruta del usuario cuyo crontab es y, en cambio, tiene la suya. Se puede cambiar fácilmente agregando PATH=/foo/bar
al principio del crontab, y la solución clásica es usar siempre rutas absolutas a los comandos ejecutados por cron, pero ¿dónde se define la RUTA predeterminada de cron?
Creé un crontab con los siguientes contenidos en mi sistema Arch (cronie 1.5.1-1) y también probé en un cuadro Ubuntu 16.04.3 LTS con los mismos resultados:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
Eso impreso:
$ cat fff
/usr/bin:/bin
¿Pero por qué? La ruta predeterminada del sistema está configurada /etc/profile
, pero eso incluye otros directorios:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
No hay nada más relevante en /etc/environment
o /etc/profile.d
, los otros archivos que pensé podrían ser leídos por 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
Tampoco hay nada relevante en ninguno de los archivos /etc/skel
, como era de esperar, ni se está configurando en ningún /etc/cron*
archivo:
$ 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
Entonces, ¿dónde se establece la RUTA predeterminada de cron para las crontabs de usuario? ¿Está codificado en cron
sí mismo? ¿No lee algún tipo de archivo de configuración para esto?
cron
mirar/etc/profile
o preocuparse por un shell en particular. Una mejor pregunta es ¿por qué nocron
leerPATH
desdelogin.defs
(en Linux) ologin.conf
(en * BSD). Supongo que en última instancia es un detalle de implementación./etc/profile
porque usa la misma sintaxis (var=value
) que encron
sí misma, por lo que sería bastante fácil de hacer y/etc/profile
, que yo sepa, está muy extendido. Lo que me sorprendió es que no pude encontrarlo en ningún lugar, por lo que parecía que estaba codificado. Como es el caso, como Stephen explicó a continuación.zsh
como su shell interactivo no les importa/etc/profile
(lo cual es específico parabash
)profile
archivos solo se leen por shells de inicio de sesión. Estos pueden o no ser interactivos.strings
contra un programa también puede ayudar a encontrar estos valores codificados.Respuestas:
Está codificado en el código fuente (ese enlace apunta al Debian actual
cron
; dada la variedad decron
implementaciones, es difícil elegir uno, pero es probable que otras implementaciones sean similares):cron
no lee las rutas predeterminadas de un archivo de configuración; Me imagino que el razonamiento es que admite la especificación de rutas que ya se utilizanPATH=
en cualquier trabajo temporal, por lo que no es necesario poder especificar un valor predeterminado en otro lugar. (El valor predeterminado codificado se usa si nada más especifica una ruta en una entrada de trabajo ).fuente
_PATH_DEFPATH_ROOT
definición, confirme (usando un trabajo cron deecho $PATH > /testfile
) después de editar el crontab de root usandocrontab -e
Debian Stretch que el crontab de root también usa_PATH_DEFPATH
, es decir, "/ usr / bin: / bin", no_PATH_DEFPATH_ROOT
. Esto también se confirma mediante el segundo enlace del código fuente en esta respuesta (en la que_PATH_DEFPATH_ROOT
no se usa). No me queda claro si esta definición huérfana es un error.Agregando a la respuesta de Stephen Kitt, hay un archivo de configuración que establece
PATH
para cron en Ubuntu, ecron
ignora esoPATH
para usar el valor predeterminado codificado (oPATH
s establecido en los propios crontabs). El archivo es/etc/environment
.cron
Configuración de PAM de la nota :Esto es fácilmente verificable. Agregue una variable para
/etc/environment
, por ejemplofoo=bar
, ejecutarenv > /tmp/foo
como cronjob y ver como sefoo=bar
muestra en la salida.Eso es cierto en Arch Linux, pero en Ubuntu, la base
PATH
está establecida/etc/environment
. Archivos en/etc/profile.d
tachuela a un existentePATH
, y puede agregarlo a él~/.pam_environment
. Tengo un error archivado sobre el comportamiento de Arch .Lamentablemente,
/etc/pam.d/cron
no incluye la lectura de~/.pam_environment
. Extrañamente,/etc/pam.d/atd
hace incluir ese archivo:... pero los comandos ejecutados
at
aparentemente heredan el entorno disponible al crear elat
trabajo (por ejemplo,env -i /usr/bin/at ...
parece ejecutar trabajos con un entorno muy limpio).Enmendar
/etc/pam.d/cron
teneruser_readenv=1
parece no causar problemas, y las variables~/.pam_environment
comenzaron a aparecer bien (exceptoPATH
, por supuesto).En total, establecer variables de entorno para cron parece ser un negocio desordenado. El mejor lugar parece estar en la especificación del trabajo en sí, aunque solo sea porque no sabe qué variables de entorno heredadas cron podría decidir ignorar (sin leer la fuente).
fuente
at
trabajos, si volca unat
trabajo, verá que configura explícitamente el entorno para que coincida con el entorno cuando se creó el trabajo.