Installing & Configuring the Cygwin Cron Service in Windows.
To set up cron on Cygwin, you'll need to install two additional cygwin packages using the cygwin setup.exe:
- cron: Vixie's Cron
- cygrunsrv: NT/W2K service initiator
Both programs are in the "Admin" category. Cron is the cron-daemon and Cygrunsrv is the program used to install & manage Cygwin programs as Windows services.
You'll also need vi(m) installed if you haven't already as it's the default editor for the crontab command. (It is possible to use another editor such as nano provided you set it as your default editor in your bash profile.)
Once you have the packages installed you can install cron as a Windows Service using Cygrunsrv.
cygrunsrv --install cron --path /usr/sbin/cron --args -n
There are a lot of web posts that say you should use cygrunsrv -I cron -p /usr/sbin/cron -a -D (See Errors #1 & #2).
By default, cron will install as a service that uses the Local System account. If you test cron at this point - for Windows 2003 at least - the windows event log will show Windows Application Event Log: (CRON) error (can't switch user context) - See error #3. This is because your test crontab is set up as the local administrator but the service is running as the 'Local System' account and does not have permission to create a token object.
To finish off the install, create a new user called cygrunsrv and use the Local Security Policy snap-in to allow that user to 'Create a token object', 'Logon as a service' & 'Replace a process level token' using the local group policy.
You will also need to add the user to the Local Administrators Group. I've added this as a note because I'm currently checking what permissions are really required. If it's possible, it would be better to not have this account added to the Local Administrators Group.
Set the service to run as .\cygrunsrv, set the password and restart the cron service.
You can start and stop the cron service by using:
- Using the Windows Services Snap-in
- From a cmd window or run dialogue; 'net start cron' & 'net stop cron'
- Or, since you are setting this up in Cygwin; 'cygrunsrv --start cron' & 'cygrunsrv --start cron'
To test the service, set up a crontab as the local administrator and check that it runs. A good test is to open a cygwin bash shell and run
This will open the crontab in vi(m). Add the following line:
* * * * * echo "Cron test at $(date +\%k:\%M)" >> /cygdrive/c/crontest.txt 2>&1
(A little tip here; if you use the date command in a cron job, you need to escape the % characters will a backslash otherwise it won't work...)
If everything is running correctly this will generate a file called c:\crontest.log and add a new line every minute.
Common errors and their solutions.
#1 cygrunsrv: Error starting a service: QueryServiceStatus: Win32 error 1062: The service has not been started.
This error appears in the Cygwin shell windows when you try to start the service. It is accompanied by error #2 in /var/log/cron.log. The resolution is the same as error #2.
You may find that although it appears that the service didn't start, it did start but just stopped again. When this happens you may find that you have a cron process running that will lead to error #4 the next time you try to start the service.
#2 cygwin cron "unknown option -- D" appears in /var/log/cron.log
To fix this use -n instead of -D: ie cygrunsrv --install cron --path /usr/sbin/cron --args -n
From the Man Page
Cron should be started from /etc/rc or /etc/rc.local. It will return immediately, so you don't need to start it with '&'. The -n option changes this default behavior causing it to run in the foreground. This can be useful when starting it out of init.
#3 Windows Application Event Log: (CRON) error (can't switch user context)
This error appears in the Windows Application Event Log and occurs because the account running the service can't switch user context. In other words, the cron service is running using one account - e.g. Local System - and can't switch to run as the account to whom the crontab being run belongs to. This can be resolved by using an account especially created for the job of running the cron server - in this how-to that account is 'cygrunsrv'.
#4 /usr/sbin/cron: can't lock /var/run/cron.pid, otherpid may be nnnn: Resource temporarily unavailable
Cron is already running a process. When you are having issues setting up cron, you may find that although the service stopped, cron is left running as an orphan process in the background. Use ps -a to find the process and then use kill -9 to finish it off!
What the switches mean in the cygrunsrv command.
cygrunsrv --install cron --path /usr/sbin/cron --args -n
The switches are:
- --install (-I) Installs the service on Windows.
- --path (-p) Gives the full path to the executable as Cygwin sees it.
- --args (-a) Passes any arguments to the executable that you might need. You can add more than one by surrounding them in double quotes.
- 'cygrunsrv --start cron' from a Cygwin shell: Starts the Cron Service
- 'net start cron' from a Windows command prompt: Starts the Cron Service
- 'cygrunsrv --stop cron' from a Cygwin shell: Stops the Cron Service
- 'net stop cron' from a Windows command prompt: Stops the Cron Service
- crontab -e: Edit a crontab
- crontab -l: List a crontab
For additional information in /var/log/cron.log you can use debug flags by adding the switch '-x'
e.g. cygrunsrv --install cron --path /usr/sbin/cron --args "-n -x sch,proc,pars,load,misc"
- sch :be verbose when iterating through the scheduling algorithms
- proc :be verbose about the state of the process, including all of its offspring
- pars :be verbose about parsing individual crontab lines
- load :be verbose when loading crontab files
- misc :be verbose about miscellaneous one-off events
- bit :currently not used
- ext :make the other debug flags more verbose
- test :trace through the execution, but do not perform any actions
Local Security Policy.
When you add the user to the service, Windows will automatically enable that user to run as a service. You can put this back to the default setting in your Local Security Policy settings.
From the openssh.README.txt (in regards to cygrunsrv).
Important note for Windows 2003 Server users:
2003 Server has a funny new feature. When starting services under SYSTEM account, these services have nearly all user rights which SYSTEM holds... except for the "Create a token object" right, which is needed to allow public key authentication :-(
There's no way around this, except for creating a substitute account which has the appropriate privileges. Basically, this account should be member of the administrators group, plus it should have the following user rights:
Create a token object
Logon as a service
Replace a process level token