如何在Windows上的Cygwin中运行crontab?

106
一些cygwin命令是.exe文件,因此您可以使用标准Windows计划程序运行它们,但其他命令没有.exe扩展名,因此无法从DOS运行(似乎如此)。
例如,我想要updatedb每晚运行。
如何使cron起作用?
8个回答

97

您还需要安装cygrunsrv,以便将cron设置为Windows服务,然后运行cron-config

如果您希望cron作业发送任何输出的电子邮件,则还需要在运行cron-config之前安装eximssmtp

有关没有.exe扩展名的程序,它们可能是某种类型的shell脚本。 如果您查看文件的第一行,您可以看到所需的程序以运行它们(例如,“#!/bin/sh”),因此您可以通过调用shell程序(例如“C:\cygwin\bin\sh.exe -l /my/cygwin/path/to/prog”)从Windows计划程序中执行它们。

请参阅/usr/share/doc/Cygwin/cron-*.README获取更多详细信息。


2
请注意,即使您明确要求不使用其他帐户,它仍将使用seteuid(或类似的东西),并显示加密且矛盾的“无法切换用户上下文”错误。在Cygwin上使用cron进行帐户切换显然是强制性的。您必须拒绝以自己的身份运行。 - user3338098
cygwin的cron的-n选项与无选项一样毫无意义,因为所有事件都会进入Windows事件日志。这是cygwin/cron文档可怕和具有欺骗性的部分。 - user3338098
3
提示:使用“cronevents”命令查看事件(从Windows事件日志中)。它们从不被丢弃,我会每几个月修剪一次日志。 - Gene Pavlovsky
这里有一些扩展文档,介绍如何解决setuid问题:https://www.davidjnice.com/cygwin_cron_service.html - Holger Böhnke

79
你有两个选择:
  1. 使用cygrunsrv将cron安装为Windows服务:

    cygrunsrv -I cron -p /usr/sbin/cron -a -n
    
    net start cron
    

    请注意,在(非常)旧的cron版本中,您需要使用-D而不是-n。

  2. '非.exe'文件可能是bash脚本,因此您可以通过调用bash运行脚本来使用Windows计划程序运行它们,例如:

    C:\cygwin\bin\bash.exe -l -c "./full-path/to/script.sh"
    

4
我特别喜欢bash.exe的方法。谢谢。 - barrypicker
4
顺便提一下,我需要将路径指定为Unix风格的路径-对于使用Windows任务计划程序安排的整个命令,看起来是这样的... c:\cygwin\bin\bash.exe -l -c "/usr/bin/updatedb" - barrypicker
2
如果这不起作用,你可能需要用 -n 替换 -D :cygrunsrv -I cron -p /usr/sbin/cron -a -n - Benlitz
2
我正在使用cygrunsrv v1.62,但'-D'不是一个有效的选项,因此服务在启动后立即退出。应该使用'-n'代替'-D',以防止服务自行退出。 - eaykin
4
如果您运行脚本,使用-l选项(登录shell)的目的是什么?通常,脚本由非登录、非交互式shell来运行 - 这种shell不会调用/etc/profile~/.bash_profile~/.bashrc,对于脚本来说这就没有太多意义了。-c选项也是不必要的,它是用于指定一个命令的,而脚本只是一个文件,可以直接传递给bash。因此,可以将其简化为 C:\cygwin\bin\bash.exe "./path/to/script.sh" - Gene Pavlovsky
显示剩余2条评论

27

致敬 http://linux.subogero.com/894/cron-on-cygwin/

启动cygwin-setup并从“Admin”类别中添加“cron”包。

我们将使用用户SYSTEM作为服务运行cron。因此,SYSTEM需要一个home目录和一个shell。这将在“/etc/passwd”文件中进行定义。

$ mkdir /root
$ chown SYSTEM:root /root
$ mcedit /etc/passwd
SYSTEM:*:......:/root:/bin/bash

启动服务:

$ cron-config
Do you want to remove or reinstall it (yes/no) yes
Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec
Do you want the cron daemon to run as yourself? (yes/no) no
Do you want to start the cron daemon as a service now? (yes/no) yes

本地用户现在可以像这样定义他们的定时任务 (crontab将启动您喜欢的编辑器):

$ crontab -e  # edit your user specific cron-table HOME=/home/foo
PATH=/usr/local/bin:/usr/bin:/bin:$PATH
# testing - one per line
* * * * *   touch ~/cron
@reboot     ~/foo.sh
45 11 * * * ~/lunch_message_to_mates.sh

域用户: 它不起作用。可怜的cron无法代表机器上的域用户运行预定任务。但还有另一种方法: cron还可以运行在“/etc/crontab”中发现的系统级别cron表中的东西。因此,将您的内容插入其中,以便SYSTEM代表自己完成它:

$ touch /etc/crontab
$ chown SYSTEM /etc/crontab
$ mcedit /etc/crontab
HOME=/root
PATH=/usr/local/bin:/usr/bin:/bin:$PATH
* * * * *   SYSTEM touch ~/cron
@reboot     SYSTEM rm -f /tmp/.ssh*

最后,关于crontab条目的几点说明。它们可以是环境设置或计划任务命令。如上所述,在Cygwin中最好创建一个可用的PATH。通常从“/etc/passwd”中获取主目录和shell。

至于计划任务命令的列,请参阅手册页面。

如果某些crontab条目未运行,则最佳诊断工具是:

$ cronevents

1
没有必要将CYGWIN设置为ntsec。它已经过时了。http://www.cygwin.com/cygwin-ug-net/using-cygwinenv.html - yam655
你如何以SYSTEM身份运行Cygwin? - niken
虽然我们使用带有AD身份验证的Cygwin SSHD,但我无法以相同的方式或使用passwd -R使cron工作。它对我有效的唯一方法是将cron作为指定用户的服务运行,并使用此用户执行所有cron作业。(Cygwin 2.8.0) - MortenB

9

我想补充一下,cron的选项似乎已经更改了。现在需要使用-n而不是-D。

cygrunsrv -I cron -p /usr/sbin/cron -a -n

3

应用了这个答案中的指示,它起作用了。 只是想指出更像复制粘贴的答案(因为Cygwin安装程序在实现上有点反对复制粘贴)。
点击WinLogo按钮,键入cmd.exe,右键单击它,选择“以管理员身份启动”。在cmd提示符下:

 cd <directory_where_i_forgot_the setup-x86_64.exe> cygwin installer:
 set package_name=cygrunsrv cron
 setup-x86_64.exe -n -q -s http://cygwin.mirror.constant.com -P %package_name%

确保安装程序在提示中没有抛出任何错误...如果有错误,你可能正在运行一些cygwin二进制文件,或者你不是Windows管理员,或者遇到了一些奇怪的bug...

现在在cmd提示符中:

 C:\cygwin64\bin\cygrunsrv.exe -I cron -p /usr/sbin/cron -a -D   

或者您拥有的cygrunsrv.exe的完整文件路径,可以在cmd提示符中将cron作为Windows服务启动

 net start cron

现在在bash终端中运行以下命令:

设置cron条目,示例如下:

        #sync my gdrive each 10th minute
    */10 * * * * /home/Yordan/sync_gdrive.sh

    # * * * * * command to be executed
    # - - - - -
    # | | | | |
    # | | | | +- - - - day of week (0 - 6) (Sunday=0)
    # | | | +- - - - - month (1 - 12)
    # | | +- - - - - - day of month (1 - 31)
    # | +- - - - - - - hour (0 - 23)
    # +--------------- minute

set package_name=cygrunsrv cron 没有工作,我不得不单独安装它们。一直收到“cygrunsrv:给定路径没有指向有效的可执行文件”的错误提示。 - rob
服务无法启动,但查看 /var/log/cron.log 后发现 -D 应该是 -n。运行 "c:\cygwin64\bin\cygrunsrv.exe -R cron" 然后运行 "c:\cygwin64\bin\cygrunsrv.exe -I cron -p /usr/sbin/cron -a -n" 解决了问题。 - rob
1
cygrunsrv:安装服务时出错:OpenSCManager:Win32错误5:拒绝访问。 - niken

3

我找到了如何在登录Windows 7时自动运行Cygwin cron服务的方法。以下是我成功的步骤:

使用记事本创建文件C:\cygwin\bin\Cygwin_launch_crontab_service_input.txt,第一行内容为no,第二行内容为yes(不包括引号)。这是你对提示的两个回答。

创建文件C:\cygwin\Cygwin_launch_crontab_service.bat,并将以下内容添加到其中:

@echo off
C:
chdir C:\cygwin\bin
bash  cron-config < Cygwin_launch_crontab_service_input.txt

在Windows启动文件夹中添加以下内容的快捷方式: Cygwin_launch_crontab_service.bat 如果需要添加到启动项,请参考http://www.sevenforums.com/tutorials/1401-startup-programs-change.html。另外,您还可以选择将以下内容添加到启动项中:
Cygwin
XWin Server 第一个是执行文件。
C:\cygwin\Cygwin.bat

第二个执行

C:\cygwin\bin\run.exe /usr/bin/bash.exe -l -c /usr/bin/startxwin.exe

2
在Cygwin中将cron安装为Windows服务的正确语法是作为参数传递-n,而不是-Dcygrunsrv --install cron --path /usr/sbin/cron --args -n 在Cygwin中启动cron时,-D会返回使用错误: $ $cygrunsrv --install cron --path /usr/sbin/cron --args -D $cygrunsrv --start cron cygrunsrv: Error starting a service: QueryServiceStatus: Win32 error 1062: The service has not been started. $cat /var/log/cron.log cron: unknown option -- D usage: /usr/sbin/cron [-n] [-x [ext,sch,proc,parc,load,misc,test,bit]] $ 以下页面有很好的解释。
在Windows中安装和配置Cygwin Cron服务: https://www.davidjnice.com/cygwin_cron_service.html P.S.我必须以管理员身份运行我的Windows 10 PC上的Cygwin64终端才能将cron安装为Windows服务。

0
Getting updatedb to work in cron on Cygwin -- debugging steps
1) Make sure cron is installed.
 a) Type 'cron' tab tab and look for completion help.
   You should see crontab.exe, cron-config, etc.  If not install cron using setup.
2) Run cron-config.  Be sure to read all the ways to diagnose cron.
3) Run crontab -e
 a) Create a test entry of something simple, e.g.,
   "* * * * * echo $HOME >> /tmp/mycron.log" and save it.
4) cat /tmp/mycron.log.  Does it show cron environment variable HOME
   every minute?
5) Is HOME correct?  By default mine was /home/myusername; not what I wanted.
   So, I added the entry
   "HOME='/cygdrive/c/documents and settings/myusername'" to crontab.
6) Once assured the test entry works I moved on to 'updatedb' by
   adding an entry in crontab.
7) Since updatedb is a script, errors of sed and find showed up in
   my cron.log file.  In the error line, the absolute path of sed referenced
   an old version of sed.exe and not the one in /usr/bin.  I tried changing my
   cron PATH environment variable but because it was so long crontab
   considered the (otherwise valid) change to be an error.  I tried an
   explicit much-shorter PATH command, including what I thought were the essential
   WINDOWS paths but my cron.log file was empty.  Eventually I left PATH alone and
   replaced the old sed.exe in the other path with sed.exe from /usr/bin.
   After that updatedb ran to completion.  To reduce the number of
   permission error lines I eventually ended up with this:
   "# Run updatedb at 2:10am once per day skipping Sat and Sun'
   "10 2  *  *  1-5  /usr/bin/updatedb --localpaths='/cygdrive/c' --prunepaths='/cygdrive/c/WINDOWS'"

Notes: I ran cron-config several times throughout this process
       to restart the cygwin cron daemon.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接