Shell

如果我在 cron 中將兩個 shell 分配給 SHELL,它可能會起作用嗎?

  • July 12, 2021

最近我開始逐步將我的 shell 切換到nu的過程 ,因此我考慮將它的路徑分配給 cron 中的 SHELL。

在閱讀了手冊的大部分內容後man 5 crontab,我查看了 PATH 並複制了:在嘗試將兩個 shell 分配給 SHELL 的值之間使用的約定:

SHELL=/bin/bash:/home/jerzy/.cargo/bin/nu

它不起作用,我的 crontab 中的腳本沒有完成它們的工作。而兩者都可以SHELL=/bin/bash正常 SHELL=/home/jerzy/.cargo/bin/nu工作。

我可以將兩個 shell 分配給 SHELL 嗎?這樣做是否有意義?

不,由於@Stephen 在他們的回答中描述的原因,擁有多個外殼SHELL沒有意義。但是,該變數僅控制 shell用於執行該行中的立即命令部分;並且至少在 Linux 系統上經常使用的 Vixie cron 中,可以在. Debian 手冊頁說:SHELL``cron``crontab``SHELL``crontab``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或其他。只需要設置為可以將等作為命令並使用參數執行該腳本的東西。大多數 shell 都同樣支持瑣碎的東西,所以如果你把複雜的東西放在單獨的腳本中並保持行簡單,你可以在腳本本身中使用任何 shell 或腳本語言。#!/usr/bin/perl``#!/bin/bash``SHELL``/path/to/somescript.py maybe``crontab


而且,如果您需要在直接 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。)

不,您不能將兩個 shell 分配給SHELL:cron需要知道要啟動哪個 shell,只能有一個。SHELL變數 incrontab沒有指定可能的shell ,它指定要使用的 shell。cron讀取 中的值SHELL(如果有),並將其用作執行命令;它不解釋:或任何其他符號。

備份也不起作用:如果某事因 而失敗nucron則無法知道它是否因nu或其他原因而失敗。大多數腳本都是為給定的解釋器(在他們的 shebang 中指定的)編寫的,你不能嘗試一次又一次地執行它們。同樣,crontab在編寫條目時要考慮到指定SHELL的內容(如果不是預設值/bin/sh)。

引用自:https://unix.stackexchange.com/questions/657804