¿Cuál es el 'directorio de trabajo' cuando cron ejecuta un trabajo?

171

Tengo un script que funciona cuando lo ejecuto desde la línea de comandos, pero cuando lo programo cronaparece errores que no puede encontrar archivos o comandos. Mi pregunta es doble:

  1. Cuando programo un trabajo cron usando crontab -e, ¿usa mi ID de usuario como base para sus permisos? ¿O utiliza una identificación de usuario cron de algún tipo y sus permisos relacionados?

  2. Cuando se inicia un trabajo cron, ¿cuál es el directorio de trabajo? ¿Es el directorio donde especifico el script para ejecutar, o un directorio diferente?

Aquí está mi trabajo cron:

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

Aquí está el guión 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

Estos son los errores que obtengo cuando veo el mailmensaje producido 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

No puede encontrar el template.txtpero reside en el mismo directorio que el script. Tampoco puede ejecutarse ssmtp, pero puedo como mi usuario. ¿Qué me falta para que esto funcione correctamente?

Aficionado profesional
fuente

Respuestas:

159

Agregue cd /home/xxxx/Documents/Scripts/si desea que su trabajo se ejecute en ese directorio. No hay razón para que cron cambie a ese directorio en particular. Cron ejecuta sus comandos en su directorio de inicio.

En cuanto a ssmtp, puede que no esté en su valor predeterminado PATH. La ruta predeterminada de Cron depende de la implementación, así que revise su página de manual, pero lo más probable ssmtpes /usr/sbinque no esté en su predeterminada PATH, solo en la raíz.

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
fuente
@Giles - Gracias, ¿ crontendría el suyo propio PATHo puedo consultar a mi usuario PATH? Configuré ssmtp para que tenga su propio permiso usery creo wheelque permitiría que cualquiera lo use (incluido cron). Si ayuda Im en CENTOS 6.2
ProfessionalAmateur
3
@ProfessionalAmateur Su problema no es que no se le permita usar ssmtp, sino que su trabajo cron no encuentra ningún ejecutable llamado ssmtpporque no está en su PATH. No existe tal cosa como "su usuario PATH"; Esta es una configuración por proceso, no una configuración por usuario. Puede establecer la ruta para todos sus trabajos cron colocando una PATH=…línea en su crontab.
Gilles
Tuve que agregar MAILTO='[email protected] 'también para que funcione junto con la configuración de RUTA. Extraño pero funcionó para mí.
mac
Para ssmtp se puede usar; ´which ssmtp´ ...
Fredrick Gauss el
@FredrickGauss Make thattype ssmtp
Gilles
20

Si su cronjob es un script bash, lo siguiente incluirá un CD en la ubicación de su script (suponiendo que esté utilizando la ruta absoluta en su definición cron):

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

Para responder la pregunta 1: si se ejecuta crontab -ecomo su propio usuario, los trabajos se programarán en el crontab de ese usuario y, por lo tanto, se ejecutarán con los permisos de ese usuario.

Pero debe tener en cuenta que los trabajos se ejecutarán en un shell no interactivo, lo que significa que $ PATH podría ser diferente del que tiene cuando ejecuta el script desde la línea de comandos.

Es mejor usar siempre rutas completas en los scripts, especialmente si planea programarlos a través de at / cron, etc.

También recomendaría usar rutas completas a todos los archivos para evitar exactamente los problemas que ve.

Para evitar condiciones de carrera y otros problemas de seguridad, también debe usar mktemppara asegurarse de que el archivo que lee no sea modificado por nada fuera de su script.

Entonces cambiaría el script a 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
fuente
7

cronejecuta los trabajos programados de cada usuario como ese usuario. Esto debería ser suficiente para que sepamos que ejecuta sus scripts en relación con su directorio de inicio.

Si necesita que se ejecute desde una ubicación diferente, simplemente use cden su script para ir a esa ubicación.

ssmtpprobablemente no esté en cronla RUTA predeterminada (está configurado para ser muy estrecho por diseño en la mayoría de las plataformas). Puede especificar la ruta completa ssmtpen su secuencia de comandos, o puede establecer explícitamente PATH en a) su archivo crontab, que estará disponible para todas sus secuencias de comandos, o b) en cada secuencia de comandos.

D_Bye
fuente
3

Verifique este hilo sobre cómo puede encontrar fácilmente el entorno de cron, es mucho menos de lo que está acostumbrado en un shell interactivo. Lo mejor es asumir que no se ha establecido nada y establecerlo explícitamente usted mismo.

jippie
fuente
1

El directorio de trabajo predeterminado para cronejecutar el trabajo es el directorio de inicio, por lo general /home/your-user-name.

Adoptando @Kusalananda excelente comentario.

Las personas inteligentes ayudan a otros
fuente
1
No. Depende de dónde guarde el sistema los directorios principales. /homeEstá lejos de ser universal.
Kusalananda
1
@Kusalananda El estándar LSB dice /home.
user259412
1
@peterh Bueno, los usos de macOS /Usersy el uso histórico de Unices /usr, e incluso en Linux, el directorio de inicio de un usuario del sistema puede estar en algún lugar debajo /varo en otro lugar.
Kusalananda
1
@Kusalananda Está bien.
user259412
Gracias, eres la única persona que realmente respondió esta pregunta :)
OwN
0

Algunas personas lo han insinuado o vinculado, pero la mejor manera de averiguarlo ya que no puedo encontrarlo en los documentos de hombre para mi distribución es simplemente agregar esto a un cron

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

En mi caso, ubuntu solo usa por defecto lo /usr/bin:/binque causó algunos problemas.

mschuett
fuente