it-swarm-eu.dev

Jak mohu říct cronovi, aby spustil příkaz každý druhý den (lichý / sudý)

Když konfigurujete cron tak, aby každý druhý den spouštěl příkaz pomocí pole „Den měsíce“:

1 22 */2 * * COMMAND

to běží pokaždé, když je den v měsíci lichý: 1,3,5,7,9 a tak dále.

Jak mohu nastavit cron tak, aby běžel ve dnech v měsíci, které jsou dokonce jako 2,6,8,10 atd. (Aniž by to byl doslovně specifikován, což je problematické, protože každý měsíc má jiný počet dní v měsíci)?

46
freddie

Syntaxe, kterou jste vyzkoušeli, je ve skutečnosti dvojznačná. V závislosti na tom, kolik dní je v měsíci, některé měsíce to poběží v lichých dnech a některé dokonce sudé. Je to proto, že způsob, jakým se počítá, bere celkový počet možností a dělí je. Toto chování s potlačením šumu můžete potlačit ručně zadáním rozsahu dne a použitím lichého nebo sudého počtu dní. Protože i dnešní skripty by nikdy neproběhly 31. den delších měsíců, nic neztratíte, pokud použijete 30 dnů jako základnu pro sudé dny, a specifikováním konkrétního rozdělení, jako by existovalo 31 dní, můžete vynutit liché -denní poprava.

Syntaxe bude vypadat takto:

# Will only run on odd days:
0 0 1-31/2 * * command

# Will only run on even days:
0 0 2-30/2 * * command

Vaše obava z toho, že měsíce nemají stejný počet dní, zde není důležitá, protože žádné měsíce nemají VÍCE dnů než toto, a ve špatném únoru se časové období nebude vždy shodovat s posledním nebo dvěma dny, ale nepoškodí to. mít to na seznamu.

Jedinou 'gotcha' pro tento přístup je, že pokud jste v lichém denním cyklu, následující měsíce s 31 dny bude váš příkaz spuštěn také v prvním měsíci. Stejně tak pokud nutíte rovnoměrný cyklus, každý skokový rok způsobí na konci února jeden třídenní cyklus. Nemůžete se opravdu obejít tím, že žádný pravidelný vzorec „každý druhý den“ nemusí vždy padnout na sudé nebo liché dny v každém měsíci a jakýmkoli způsobem ho nutíte, budete mít buď další běh, nebo vám bude chybět běh mezi měsíce s neshodným dnem se počítá.

64
Caleb

Myslím, že možnost používá den v roce, jako je tento:

# for odd days
test $(((`date +%j` % 2))) != 0 && command

# for even days
test $(((`date +%j` % 2))) == 0 && command

Je testován na systémy Unix a Linux.

2
Jordi

Obecně bych to spouštěl každý den a nechal skript používat logiku, abych zjistil, zda by měl být spuštěn dnes.

Vytvoření jednoduchého stavového souboru sdělením, kdy bylo naposledy spuštěno a poté kompairováním, by fungovalo velmi snadno.

Pokud je třeba ji spouštět z různých zdrojů, udělejte to na argumentech.

1
Klas Mattsson

Podívejme se každý den, jestli se jedná o „jiný“ :-) (je vyžadován program bc)

0 0 * * * test $(echo `date +%s` / 86400 % 2 == 0 |bc) -eq 0 && command

(Nejsem si jistý, zda se kód zobrazí správně. date +%s část je mezi zpětnými apostrofy.)

1
user37264