最近我开始逐渐将 shell 切换到怒 正因为如此,我考虑将其路径分配给 cron 中的 SHELL。
阅读了手册的大部分内容后man 5 crontab
,我查看了 PATH 并复制了在:
尝试将两个 shell 分配给 SHELL 的值之间使用 in 的约定:
SHELL=/bin/bash:/home/jerzy/.cargo/bin/nu
它不起作用,我的 crontab 中的脚本没有完成它们的工作。而 和 都SHELL=/bin/bash
工作
SHELL=/home/jerzy/.cargo/bin/nu
得很好。
我可以给SHELL分配两个shell吗?这样做有意义吗?
答案1
不,您不能将两个 shell 分配给SHELL
:cron
需要知道要启动哪个 shell,只能有一个。SHELL
中的变量未crontab
指定可能的shell,它指定这外壳来使用。cron
读取 中的值SHELL
(如果有),并将其用作运行命令;它不解释:
或任何其他符号。
后备也不起作用:如果某件事因 失败nu
,cron
则无法知道它是因为nu
还是其他原因而失败。大多数脚本都是为给定的解释器(在其 shebang 中指定)编写的,您不能尝试使用一个解释器运行它们,然后再使用另一个解释器运行它们。同样,crontab
条目的编写是SHELL
考虑到指定的(如果不是默认的/bin/sh
)。
答案2
不,有多个 shellSHELL
是没有意义的,原因如下@Stephen 在他们的回答中描述了。但是,该SHELL
变量仅控制 shellcron
用于运行该crontab
行中的立即命令部分;至少在 Linux 系统上经常使用的 Vixie cron 中,SHELL
可以在crontab
.这Debian 手册页说crontab(5)
:
crontab 文件是从上到下解析的,因此任何环境设置都只会影响文件中位于其下方的 cron 命令。
这句话看起来可能是 Debian 添加的,但在我尝试过的 CentOS 系统上似乎效果相同。但正如 Toby Speight 的评论中所指出的,环境变量赋值crontab
根本不是 POSIX 功能,所以 YMMV。
因此,无论 cron 如何,您都应该能够执行以下操作:
* * * * * /path/to/somescript.py maybe
* * * * * /path/to/otherscript.pl some
* * * * * /path/to/thirdscript.sh args
其中脚本有正确的 hashbang 行,例如#!/usr/bin/python3
、#!/usr/bin/perl
或#!/bin/bash
其他。SHELL
只需要设置为可以将/path/to/somescript.py maybe
等作为命令并使用参数运行该脚本的东西。大多数 shell 都相同地支持琐碎的内容,因此,如果您将复杂的内容放在单独的脚本中并保持行crontab
简单,则可以在脚本本身中使用任何 shell 或脚本语言。
而且,如果您需要在直接 crontab 命令中使用不同的 shell,您可以这样做,至少在 Vixie cron 中:
SHELL=/bin/bash
* * 8-14 * * if test "$(date +\%w)" = 0; then echo $BASH_VERSION > /tmp/bashtest; fi
SHELL=/usr/bin/fish
* * 8-14 * * if test (date +\%w) = 0; echo $FISH_VERSION > /tmp/fishtest; end
两者都检查当天是否是星期日,如果是,则打印 shell 版本,一种使用 Bash,一种使用 Fish。 (当然,这只是一个示例,但由于 cron 时间设置的工作方式,在一个月的第一个/第二个/最后一个特定工作日运行是您可能希望在 crontab 上使用 shell 代码的常见情况之一命令。)
另外,顺便说一句,您在评论中提到 Nu 不支持带有 的多行命令\
,并且希望您可以在那里使用 Bash。请注意,crontab 行中不能有多行命令:命令本身必须位于文件中的一行上,并且当cron
采用%
符号作为换行符时,第一行后面的行将发送到命令。 (这就是为什么我们需要转义上面%
格式字符串中使用的内容date
。)