¿Cómo crear un trabajo cron usando Bash automáticamente sin el editor interactivo?


Crontab tiene un argumento para crear trabajos cron sin usar el editor (crontab-e). Si es así, ¿cuál sería el código create a cronjob from a Bash script?

16 answers

Puede agregar al crontab de la siguiente manera:

#write out current crontab
crontab -l > mycron
#echo new cron into cron file
echo "00 09 * * 1-5 echo hello" >> mycron
#install new cron file
crontab mycron
rm mycron

Explicación de la línea Cron

* * * * * "command to be executed"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

Source nixCraft .

 414
Author: dogbane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-09 15:20:04

Usted puede ser capaz de hacerlo sobre la marcha

crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -

crontab -l enumera los trabajos crontab actuales, cat los imprime, echo imprime el nuevo comando y crontab - agrega todo el material impreso al archivo crontab. Puedes ver el efecto haciendo un nuevo crontab -l.

 253
Author: TheBonsai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 11:10:19

Este más corto no requiere ningún archivo temporal, es inmune a múltiples inserciones, y le permite cambiar la programación de una entrada existente.

Di que tienes estos:

croncmd="/home/me/myfunction myargs > /home/me/myfunction.log 2>&1"
cronjob="0 */15 * * * $croncmd"

Para añadirlo al crontab, sin duplicación:

( crontab -l | grep -v -F "$croncmd" ; echo "$cronjob" ) | crontab -

Para eliminarlo del crontab sea cual sea su horario actual:

( crontab -l | grep -v -F "$croncmd" ) | crontab -

Notas:

  • grep-F coincide literalmente con la cadena, ya que no queremos interpretarla como una expresión regular
  • También ignoramos el tiempo programación y solo busque el comando. De esta manera; el horario se puede cambiar sin el riesgo de agregar una nueva línea al crontab
 57
Author: MoonCactus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-13 07:46:03

Gracias a todos por su ayuda. Juntando lo que encontré aquí y en otros lugares, se me ocurrió esto:

El Código

command="php $INSTALL/indefero/scripts/gitcron.php"
job="0 0 * * 0 $command"
cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -

No podía averiguar cómo eliminar la necesidad de las dos variables sin repetirme.

command obviamente es el comando que quiero programar. job toma $command y agrega los datos de programación. Necesitaba ambas variables por separado en la línea de código que hace el trabajo.

Detalles

  1. Crédito a duckyflip, I use esta pequeña redirección (<(*command*)) para convertir la salida de crontab -l en entrada para el comando fgrep.
  2. fgrep luego filtra cualquier coincidencia de $command (-v opción), insensible a mayúsculas y minúsculas (opción-i).
  3. De nuevo, la pequeña redirección (<(*command*)) se usa para convertir el resultado de nuevo en entrada para el comando cat.
  4. El comando cat también recibe echo "$job" (autoexplicativo), nuevamente, a través del uso de la redirección (<(*command*)).
  5. Así que la salida filtrada de crontab -l y los simples echo "$job", combinados, son canalizados ('|') a crontab - para finalmente ser escritos.
  6. Y todos vivieron felices para siempre!

En pocas palabras:

Esta línea de código filtra cualquier trabajo cron que coincida con el comando, luego escribe los trabajos cron restantes con el nuevo, actuando efectivamente como una función "add" o "update". Para usar esto, todo lo que tienes que hacer es intercambiar los valores para las variables command y job.

 37
Author: Stoutie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-12 18:24:24

EDITAR (sobrescritura fija):

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -
 23
Author: duckyflip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-18 21:49:53

Ha habido muchas buenas respuestas en torno al uso de crontab, pero no se menciona un método más simple, como usar cron.

Usar cron aprovecharía los archivos y directorios del sistema ubicados en /etc/crontab, /etc/cron.daily,weekly,hourly o /etc/cron.d/:

cat > /etc/cron.d/<job> << EOF
SHELL=/bin/bash 
PATH=/sbin:/bin:/usr/sbin:/usr/bin 
MAILTO=root HOME=/  
01 * * * * <user> <command>
EOF

En este ejemplo anterior, creamos un archivo en /etc/cron.d/, proporcionamos las variables de entorno para que el comando se ejecute correctamente, y proporcionamos el user para el comando, y el command en sí. Este archivo no debe ser ejecutable y el el nombre solo debe contener caracteres alfanuméricos y guiones (más detalles a continuación).

Para dar una respuesta completa, veamos las diferencias entre crontab vs cron/crond:

crontab -- maintain tables for driving cron for individual users

Para aquellos que quieren ejecutar el trabajo en el contexto de su usuario en el sistema, usar crontab puede tener mucho sentido.

cron -- daemon to execute scheduled commands

Para aquellos que usan gestión de configuración o quieren administrar trabajos para otros usuarios, en cuyo caso debemos usar cron.

Un breve extracto de las páginas de manual le da algunos ejemplos de lo que debe y no debe hacer:

/etc/crontab y los ficheros en /etc/cron.d debe ser propiedad de root, y no debe ser de grupo u otro tipo de escritura. En contraste con el área de spool, los archivos bajo /etc/cron.d o los archivos bajo /etc / cron.cada hora,/etc / cron.diario, /etc/cron.semanal y /etc/cron.mensualmente también pueden ser enlaces simbólicos, siempre que tanto el enlace simbólico como el archivo al que apunta sean propiedad de root. Los archivos bajo /etc / cron.d no necesita para ser ejecutables, mientras que los archivos bajo/etc / cron.cada hora,/etc / cron.diario, /etc/cron.semanal y /etc/cron.hacer mensualmente, ya que son ejecutadas por run-parts(vea run-parts (8) para más información).

Fuente: http://manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

Administrar crons de esta manera es más fácil y escalable desde la perspectiva del sistema, pero no siempre será la mejor solución.

 8
Author: Mike Mackintosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-13 21:46:13

Una variante que solo edita crontab si la cadena deseada no se encuentra allí:

CMD="/sbin/modprobe fcpci"
JOB="@reboot $CMD"
TMPC="mycron"
grep "$CMD" -q <(crontab -l) || (crontab -l>"$TMPC"; echo "$JOB">>"$TMPC"; crontab "$TMPC")
 5
Author: Gerald Schade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-21 10:50:03

Lo más probable es que esté automatizando esto y no quiera que se agregue un solo trabajo dos veces. En ese caso use:

__cron="1 2 3 4 5 /root/bin/backup.sh"
cat <(crontab -l) |grep -v "${__cron}" <(echo "${__cron}")

Esto solo funciona si estás usando BASH. No conozco la sintaxis correcta de DASH (sh).

Update: Esto no funciona si el usuario no tiene un crontab todavía. Una manera más confiable sería:

(crontab -l ; echo "1 2 3 4 5 /root/bin/backup.sh") | sort - | uniq - | crontab - 

Alternativamente, si su distro lo soporta, también puede usar un archivo separado:

echo "1 2 3 4 5 /root/bin/backup.sh" |sudo tee /etc/crond.d/backup

Los encontró en otro SO pregunta.

 5
Author: kvz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-28 11:37:00

Para una creación/sustitución rápida y sucia de un crontab de con un script BASH, usé esta notación:

crontab <<EOF
00 09 * * 1-5 echo hello
EOF
 3
Author: Gibbsoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-29 17:02:58

Si está usando Vixie Cron, por ejemplo en la mayoría de las distribuciones de Linux, puede poner un archivo en /etc/cron.d con el cronjob individual.

Esto solo funciona para root, por supuesto. Si su sistema admite esto, debería ver varios ejemplos allí. (Tenga en cuenta el nombre de usuario incluido en la línea, en la misma sintaxis que el antiguo /etc/crontab)

Es un triste error en cron que no hay manera de manejar esto como un usuario regular, y que tantas implementaciones de cron no tienen manera en absoluto para manejar esto.

 2
Author: chuck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-22 21:28:56

Aquí hay una función bash para agregar un comando a crontab sin duplicación

function addtocrontab () {
  local frequency=$1
  local command=$2
  local job="$frequency $command"
  cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -
}
addtocrontab "0 0 1 * *" "echo hello"
 1
Author: Klas Mellbourn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-03 20:48:19
CRON="1 2 3 4 5 /root/bin/backup.sh" 
cat < (crontab -l) |grep -v "${CRON}" < (echo "${CRON}")

Agregar el parámetro-w al comando grep exact, sin el parámetro-w al agregar el cronjob " testing "causa la eliminación del trabajo cron"testing123"

Función de script para añadir/eliminar cronjobs. no hay entradas duplicadas:

cronjob_editor () {         
# usage: cronjob_editor '<interval>' '<command>' <add|remove>

if [[ -z "$1" ]] ;then printf " no interval specified\n" ;fi
if [[ -z "$2" ]] ;then printf " no command specified\n" ;fi
if [[ -z "$3" ]] ;then printf " no action specified\n" ;fi

if [[ "$3" == add ]] ;then
    # add cronjob, no duplication:
    ( crontab -l | grep -v -F -w "$2" ; echo "$1 $2" ) | crontab -
elif [[ "$3" == remove ]] ;then
    # remove cronjob:
    ( crontab -l | grep -v -F -w "$2" ) | crontab -
fi 
} 
cronjob_editor "$1" "$2" "$3"

Probado:

$ ./cronjob_editor.sh '*/10 * * * *' 'echo "this is a test" > export_file' add
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file
 1
Author: speefak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-04 12:47:31

No, no hay ninguna opción en crontab para modificar los archivos cron.

Tiene que: tomar el archivo cron actual (crontab-l > newfile), cambiarlo y poner el nuevo archivo en su lugar (crontab newfile).

Si está familiarizado con perl, puede usar este módulo Config::Crontab.

LLP, Andrea

 0
Author: andcoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-18 16:53:51

Función de script para añadir cronjobs. comprobar entradas duplicadas, expresiones utilizables * > "

cronjob_creator () {         
# usage: cronjob_creator '<interval>' '<command>'

  if [[ -z $1 ]] ;then
    printf " no interval specified\n"
elif [[ -z $2 ]] ;then
    printf " no command specified\n"
else
    CRONIN="/tmp/cti_tmp"
    crontab -l | grep -vw "$1 $2" > "$CRONIN"
    echo "$1 $2" >> $CRONIN
    crontab "$CRONIN"
    rm $CRONIN
fi
}

Probado:

$ ./cronjob_creator.sh '*/10 * * * *' 'echo "this is a test" > export_file'
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file

Fuente : mi cerebro;)

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-03 20:52:53

Mi solución preferida para esto sería esta:

(crontab -l | grep . ; echo -e "0 4 * * * myscript\n") | crontab -

Esto asegurará que esté manejando correctamente la nueva línea en blanco en la parte inferior. Para evitar problemas con crontab, generalmente debe terminar el archivo crontab con una línea nueva en blanco. Y el script anterior se asegura de que primero elimine las líneas en blanco con el " grep ."part, y luego agregue una nueva línea en blanco al final con el "\n " al final del script. Esto también evitará obtener una línea en blanco por encima de su nuevo comando si su el archivo crontab existente termina con una línea en blanco.

 0
Author: gsus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-08 12:29:34

Probablemente puede cambiar el editor predeterminado a ed y usar un heredoc para editar.

EDITOR=ed
export EDITOR

crontab -e << EOF
> a
> * * * * * Myscript
> * * * * * AnotherScript
> * * * * * MoreScript
> .
> w
> q
> EOF

Tenga en cuenta el principio > en ese código significa que se presiona la tecla return/enter para crear una nueva línea.

El a significa ANEXAR para que no sobrescriba nada.

El . significa que has terminado de editar.

La w significa ESCRIBIR los cambios.

El q significa SALIR o salir eréctil.

Puedes echarle un vistazo

crontab -l

También puede eliminar una entrada.

EDITOR=ed
export EDITOR

crontab -e << EOF
> /Myscript/
> d
> .
> w
> q
> EOF

Que eliminará la entrada crontab con Myscript en ella.

La d significa eliminar el patrón dentro de la / /.

No vuelva a comprobarlo

crontab -l

Esta solución funciona dentro de un script> por supuesto: -)

 -4
Author: Jetchisel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-14 07:26:59