Ваш скрипт не видит переменные среды при запуске в качестве задания cron.

Ваш скрипт не видит переменные среды при запуске в качестве задания cron.

Когда я вызываю скрипт из ( 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.

Я вызываю скрипт из rootcronjob ( ), и он завершается с ошибкой «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

Связанный контент