我写了一篇小工具用 C++ 进行编译,使其可执行,然后将其移动到/opt/tools/bin。后者是我创建的用于存储小型自定义程序的目录。我export
将其$PATH
放在我的.zprofile,让我tool
在终端中使用,程序运行良好。
然而,当我尝试设置一个 cron 任务tool
每天运行几次时,cron 总是抱怨“/bin/sh:./tool:没有这样的文件或目录”。
我尝试了这两个 cron 命令,结果相同:
0 8,12,16,20 * * * zhrdct >> /opt/tools/var/log/zhrdct.log 2>&1
0 8,12,16,20 * * * ./zhrdct >> /opt/tools/var/log/zhrdct.log 2>&1
这可能是什么问题?
我知道我可以使用绝对路径来工具但如果可能的话我希望它能与速记一起使用。
答案1
您应该cron
始终使用可执行文件的完整路径。它在完全不同的环境中运行,并且许多可执行文件都“无法访问”
0 8,12,16,20 * * * /path/to/zhrdct >> /opt/tools/var/log/zhrdct.log 2>&1
答案2
Cron 在非交互式 shell 中运行,因此您从常规 bash 提示符(配置的 PATH、环境变量)中看到的许多功能将会不同或完全缺失。
如果您想在 cron 中省略绝对路径,则需要从头开始配置 PATH,因为没有隐式 PATH 变量可供使用:
PATH=/opt/tools/bin:/usr/bin:/bin
0 8,12,16,20 * * * zhrdct >> /opt/tools/var/log/zhrdct.log 2>&1
注意:如果您的脚本包含任何其他二进制文件的简写路径,您需要确保这些路径也添加到 PATH 中。
答案3
这里有两个问题:
该目录
/opt/tools/bin
不会是作业$PATH
的默认目录cron
。您可以像这样添加它crontab
:PATH=/opt/tools/bin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin 0 8,12,16,20 * * * zhrdct >> /opt/tools/var/log/zhrdct.log 2>&1
通常,特别是使用 时
crontab
,当您运行 时,zhrdct
系统会在 中列出的目录中搜索$PATH
指定的命令。如果找不到,则会返回command not found
您遇到的错误。但是,如果您指定命令的路径,如./zhrdct
或 ,则/opt/tools/bin/zhrdct
此搜索将被禁用,并直接按指定执行命令。如果
./zhrdct
点代表“当前目录“。crontab
如果你很幸运,那将是你的主目录($HOME
),但很有可能它可能是其他未指定的地方。你有三个选择- 设置当前目录(
cd "$HOME" && …commands to run from HOME…
) $PATH
设置已描述的搜索并运行zhrdct
- 使用命令的绝对路径,例如
/opt/tools/bin/zhrdct
。
- 设置当前目录(
请注意,在任何情况下,./zhrdct
如果命令位于 中/opt/tools/bin
并且cron
的当前目录不是/opt/tools/bin
其本身,则会失败。
答案4
另一个选择是将编译后的二进制文件存储在示例位置,并附加版本号
这会给你一系列版本 — — 例如:
/opt/tools/bin/zhrdct-1.0.0
/opt/tools/bin/zhrdct-1.0.1
/opt/tools/bin/zhrdct-1.2.0
然后为了方便起见,你/usr/local/bin/tool
可以使用以下符号链接到默认运行的任何版本:
sudo ln -s /opt/tools/bin/zhrdct-1.0.1 /usr/local/bin/tool
在目录列表中,它将显示为
lrwxrwxrwx 1 root root 11 May 16 14:35 tool -> /opt/tools/bin/zhrdct-1.0.1
您可以简单地tool
在提示符下运行或从 cron 调用,因为/usr/local/bin
它应该已经在您的路径中了。
您也应该能够将其添加到您的部署系统中,无论是 Makefile 还是 shell 脚本,或者更复杂的东西,如 salt 或 ansible 或...
另一个好处是,如果某些东西仍然需要该工具的版本 1,则可以直接调用该版本,或者使用名为的第二个符号链接tool-1
。