Cuando llamo a un script desde un root
cronjob (), falla y aparece el mensaje "ipset no encontrado". Aquí está la línea de script problemática:
for i in $(cat /etc/cn.zone); do ipset -A china $i; done
Algunas líneas antes en el script se llama este comando:
ipset -N china hash:net
Entonces, el ipset en cuestión fue creado.
Si ejecuto este script desde el directorio de inicio de la raíz, se ejecuta sin problemas.
¿Alguna idea de qué podría causar el error?
Respuesta1
Su secuencia de comandos no ve las variables de entorno cuando se ejecuta como una tarea cron.
Llamo a un script desde un
root
cronjob () y falla con el mensaje 'ipset no encontrado'...
¿Está ejecutando este script como un script Bash? ¿Qué es lo que son la mayoría de los scripts de shell hoy en día?
Si es así, cambie la primera línea de su script de
#!/bin/bash
A esto:
#!/bin/bash -l
Agregar -l
le dice a Bash que se ejecute como si hubiera sido invocado como un shell de inicio de sesión. Y si el script Bash se ejecuta a través del shell de inicio de sesión en ese trabajo cron, todas las variables de entorno (y otros elementos) que normalmente se configuran a través del shell de inicio de sesión estarán disponibles para ese script Bash, lo que permitirá ipset
que se ejecute como se esperaba.
Otro truco que puedes hacer es usarlo which
dentro de una variable Bash como esta; claramente lo estás usando, por $(cat /etc/cn.zone)
lo que el mecanismo es similar:
$(which ipset)
Y en tu script cambia tu línea a esta:
for i in $(cat /etc/cn.zone); do $(which ipset) -A china $i; done
Lo que eso hará es, mediante el uso which
, darle a su secuencia de comandos la ruta completa a ipset
(algo como /sbin/ipset
) en cualquier sistema en el que esté ejecutando esto. Y luego, configurarlo como una variable analizada $()
permitirá que el script lo ejecute.
Pero como usas ipset
otra parte de tu script, te recomendaría, si usas este which
método, que refactorices tu script para establecerlo ipset
como una variable como esta cerca de la parte superior de tu script:
ipset_bin=$(which ipset);
Y luego llama a tus comandos así:
$ipset_bin -N china hash:net
Y esto:
for i in $(cat /etc/cn.zone); do $ipset_bin -A china $i; done
Respuesta2
Su shell sabe dónde encontrar ejecutables, como ipset
buscar en su PATH
, que está configurado por su entorno, pero cron
no comparte ese mismo entorno.
Agregar esto en la parte superior de crontab
(o de su secuencia de comandos) debería indicarle dónde encontrar los comandos tal como lo esperaba:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin