Когда я вызываю скрипт из ( root
) cronjob, он вылетает с сообщением 'ipset not found'. Вот проблемная строка скрипта:
for i in $(cat /etc/cn.zone); do ipset -A china $i; done
Несколькими строками ранее в скрипте эта команда вызывается:
ipset -N china hash:net
Таким образом, рассматриваемый ipset действительно был создан.
Если я запускаю этот скрипт из домашнего каталога root, он выполняется безупречно.
Есть ли у вас идеи, что может быть причиной ошибки?
решение1
Ваш скрипт не видит переменные среды при запуске в качестве задания cron.
Я вызываю скрипт из
root
cronjob ( ), и он завершается с ошибкой «ipset not found»…
Вы запускаете этот скрипт как скрипт Bash, каковыми в настоящее время являются большинство скриптов оболочки?
Если так, то измените первую строку вашего скрипта с
#!/bin/bash
К этому:
#!/bin/bash -l
Добавление -l
сообщает Bash о необходимости запуска, как если бы он был вызван как оболочка входа. И если скрипт Bash запускается через оболочку входа в этом задании cron, все переменные среды и другие элементы, которые обычно устанавливаются через оболочку входа, будут доступны для этого скрипта Bash, что позволяет ipset
запустить его так, как и ожидалось.
Другой трюк, который вы можете сделать, — это использовать which
переменную Bash следующим образом; вы явно используете ее для, $(cat /etc/cn.zone)
поэтому механизм аналогичен:
$(which ipset)
И в вашем скрипте измените строку на эту:
for i in $(cat /etc/cn.zone); do $(which ipset) -A china $i; done
Что это сделает — используя which
— дайте вашему скрипту полный путь к ipset
(что-то вроде /sbin/ipset
) на любой системе, на которой вы это запустите. А затем установка его как анализируемой переменной через $()
позволит самому скрипту запустить его.
Но поскольку вы используете его ipset
в других местах своего скрипта, я бы рекомендовал — если вы используете этот which
метод — реорганизовать свой скрипт, чтобы установить его ipset
в качестве переменной, например, в верхней части скрипта:
ipset_bin=$(which ipset);
А затем вызовите свои команды следующим образом:
$ipset_bin -N china hash:net
И это:
for i in $(cat /etc/cn.zone); do $ipset_bin -A china $i; done
решение2
Ваша оболочка знает, где найти исполняемые файлы, например, ipset
просматривая ваш PATH
, который задается вашей средой, но cron
не использует эту же среду.
Добавление этого в начало crontab
(или вашего скрипта) должно указать, где найти команды, как вы и ожидаете:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin