当作为 cron 作业运行时,您的脚本看不到您的环境变量。

当作为 cron 作业运行时,您的脚本看不到您的环境变量。

当我从 ( ) cronjob 调用脚本时,root它会失败并显示消息“未找到 ipset”。以下是有问题的脚本行:

for i in $(cat /etc/cn.zone); do ipset -A china $i; done

脚本中之前的一些行调用了此命令:

ipset -N china hash:net

因此,所讨论的 ipset 实际上已经被创建了。

如果我从 root 的主目录运行此脚本,它可以完美运行。

知道什么可能导致错误吗?

答案1

当作为 cron 作业运行时,您的脚本看不到您的环境变量。

我从 () cronjob 调用一个脚本root,但脚本失败并显示“未找到 ipset”消息...

您是否将此脚本作为 Bash 脚本运行;目前大多数 shell 脚本都是这样的?

如果是这样,那么将脚本的第一行从

#!/bin/bash

对此:

#!/bin/bash -l

添加-l告诉 Bash 像被调用为登录 shell 一样运行。如果 Bash 脚本通过该 cron 作业中的登录 shell 运行,则通常通过登录 shell 设置的所有环境变量(以及其他项目)都将可用于该 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

您的 shell 知道在哪里找到可执行文件,例如ipset通过查看您的PATH,它由您的环境设置,但cron不共享相同的环境。

将其添加到(或您的脚本)的顶部crontab应该会告诉它在哪里找到命令,正如您所期望的那样:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

相关内容