202 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			202 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								title: Automating Tasks
							 | 
						||
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Automating Tasks or Task Scheduling
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								There is a feature of Linux that is exclusively leveraged in a web server,known as CRON 
							 | 
						||
| 
								 | 
							
								As we  know that one of the most compelling features about any web server is that it's always
							 | 
						||
| 
								 | 
							
								powered on and always connected to the internet. This means that we can instruct
							 | 
						||
| 
								 | 
							
								our server to perform tasks automatically, without us needing to enter a command
							 | 
						||
| 
								 | 
							
								into a shell. One of the most commonly used programs for executing *other programs*
							 | 
						||
| 
								 | 
							
								with a regular frequency is called `cron`. Let's take a look at how to use
							 | 
						||
| 
								 | 
							
								`cron` to schedule a program to be run.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The `cron` program is part of a family of programs called **daemons**. A daemon
							 | 
						||
| 
								 | 
							
								is a program that is always running in the background of our computer. First, 
							 | 
						||
| 
								 | 
							
								let's see if `cron` is running. We can get a list of all running programs
							 | 
						||
| 
								 | 
							
								with the `ps` command while using the `-A` flag:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```{r, engine='bash', eval=FALSE}
							 | 
						||
| 
								 | 
							
								ps -A
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								##  PID TTY          TIME CMD
							 | 
						||
| 
								 | 
							
								##    1 ?        00:00:13 systemd
							 | 
						||
| 
								 | 
							
								##    2 ?        00:00:00 kthreadd
							 | 
						||
| 
								 | 
							
								##    3 ?        00:00:03 ksoftirqd/0
							 | 
						||
| 
								 | 
							
								##    5 ?        00:00:00 kworker/0:0H
							 | 
						||
| 
								 | 
							
								##    7 ?        00:00:11 rcu_sched
							 | 
						||
| 
								 | 
							
								##    8 ?        00:00:00 rcu_bh
							 | 
						||
| 
								 | 
							
								##    9 ?        00:00:00 migration/0
							 | 
						||
| 
								 | 
							
								## ...
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You probably have a huge list of programs in your terminal now! Instead of
							 | 
						||
| 
								 | 
							
								shifting through this listing line-by-line, let's pipe the output of this command
							 | 
						||
| 
								 | 
							
								to `grep` and we'll look for `cron`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```{r, engine='bash', eval=FALSE}
							 | 
						||
| 
								 | 
							
								ps -A | grep "cron"
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								##  1273 ?        00:00:01 cron
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								# You might or might not get a `cron` running .
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Looks like the `cron` daemon is running! In order to assign programs to be
							 | 
						||
| 
								 | 
							
								executed with `cron` we need to edit a special text file called the `cron`
							 | 
						||
| 
								 | 
							
								table. Before we edit the `cron` table we need to select the default text
							 | 
						||
| 
								 | 
							
								editor. If you like using `nano` (the text editor we've been using throughout
							 | 
						||
| 
								 | 
							
								this book) then enter `select-editor` into the console, type in the number
							 | 
						||
| 
								 | 
							
								that corresponds to `nano` (usually `2`) and then press enter:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```{r, engine='bash', eval=FALSE}
							 | 
						||
| 
								 | 
							
								select-editor
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								## Select an editor.  To change later, run 'select-editor'.
							 | 
						||
| 
								 | 
							
								##   1. /bin/ed
							 | 
						||
| 
								 | 
							
								##   2. /bin/nano        <---- easiest
							 | 
						||
| 
								 | 
							
								##   3. /usr/bin/vim.basic
							 | 
						||
| 
								 | 
							
								##   4. /usr/bin/vim.tiny
							 | 
						||
| 
								 | 
							
								## 
							 | 
						||
| 
								 | 
							
								## Choose 1-4 [2]:
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Now that we've chosen a text editor we can edit the `cron` table using the
							 | 
						||
| 
								 | 
							
								command `crontab -e` (**`cron`** **tab**le **e**dit) which will automatically
							 | 
						||
| 
								 | 
							
								open `nano` with the appropriate file.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```{r, engine='bash', eval=FALSE}
							 | 
						||
| 
								 | 
							
								crontab -e
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								# Edit this file to introduce tasks to be run by cron.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# m h  dom mon dow   command
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's go over the layout of the `cron` table. First you should notice that any
							 | 
						||
| 
								 | 
							
								text after a pound sign (`#`) is a comment, so it's not seen by `cron` (just
							 | 
						||
| 
								 | 
							
								like bash comments). The `cron` table has six columns:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1. Minute (`m`)
							 | 
						||
| 
								 | 
							
								2. Hour (`h`)
							 | 
						||
| 
								 | 
							
								3. Day of Month (`dom`)
							 | 
						||
| 
								 | 
							
								4. Month (`mon`)
							 | 
						||
| 
								 | 
							
								5. Day of Week (`dow`)
							 | 
						||
| 
								 | 
							
								6. Command to be run (`command`)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Each column is separated by a single space in the table. The first five columns 
							 | 
						||
| 
								 | 
							
								allow you to specify when you want a particular command to be run. Only certain 
							 | 
						||
| 
								 | 
							
								values are valid in each column:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1. Minute: `00 - 59` (A particular minute in an hour)
							 | 
						||
| 
								 | 
							
								2. Hour: `00 - 23` (0 is the midnight hour)
							 | 
						||
| 
								 | 
							
								3. Day of Month: `01 - 31` (1 is the first day of the month)
							 | 
						||
| 
								 | 
							
								4. Month: `01 - 12` (1 is January)
							 | 
						||
| 
								 | 
							
								5. Day of Week `0 - 6` (0 is Sunday)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								There are also a few other characters that are valid in the `cron` table. The
							 | 
						||
| 
								 | 
							
								most commonly used character is a star (`*`) which represents *all* of the
							 | 
						||
| 
								 | 
							
								possible values in a column. So a star in the Minute column means "run every
							 | 
						||
| 
								 | 
							
								minute," and a star in the Hour column means "run during every hour."
							 | 
						||
| 
								 | 
							
								Knowing this let's make our first entry in the `cron` table. If we want a
							 | 
						||
| 
								 | 
							
								command to be executed every minute, during every hour, on every day of the
							 | 
						||
| 
								 | 
							
								month, during every month, on every day of the week, then we can put stars in
							 | 
						||
| 
								 | 
							
								all of the first five
							 | 
						||
| 
								 | 
							
								columns, followed by the command that we want to run. In this case the command
							 | 
						||
| 
								 | 
							
								that `cron` will run every minute will be `date >> ~/date-file.txt`, which will
							 | 
						||
| 
								 | 
							
								append the date and time when the command is executed to a file in our home
							 | 
						||
| 
								 | 
							
								directory called `date-file.txt`. This is what your `cron` table should look
							 | 
						||
| 
								 | 
							
								like before you save and exit from `nano`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								# Edit this file to introduce tasks to be run by cron.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# m h  dom mon dow   command
							 | 
						||
| 
								 | 
							
								* * * * * date >> ~/date-file.txt
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Save and exit `nano` just like you would for a regular text file and then wait
							 | 
						||
| 
								 | 
							
								a little bit! After a minute has gone by use `cat` to look at `~/date-file.txt`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```{r, engine='bash', eval=FALSE}
							 | 
						||
| 
								 | 
							
								cd
							 | 
						||
| 
								 | 
							
								cat date-file.txt
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								## Thu Jun  8 18:50:01 UTC 2017
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Look like our entry in the `cron` table is working! Wait another minute and then
							 | 
						||
| 
								 | 
							
								look at the file again:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```{r, engine='bash', eval=FALSE}
							 | 
						||
| 
								 | 
							
								cat date-file.txt
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								## Thu Jun  8 18:50:01 UTC 2017
							 | 
						||
| 
								 | 
							
								## Thu Jun  8 18:51:01 UTC 2017
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Unless we delete the line that we entered in the `cron` table, the output from
							 | 
						||
| 
								 | 
							
								`date` will be appended to `date-file.txt` every minute.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The single line of bash `date >> ~/date-file.txt` is a much simpler program than
							 | 
						||
| 
								 | 
							
								we would probably use in a `cron` table, though it's good for illustrating how
							 | 
						||
| 
								 | 
							
								a `cron` table works. If you want to do more complex tasks with `cron` it's
							 | 
						||
| 
								 | 
							
								better for `cron` to execute a bash script that you've written in advance. That
							 | 
						||
| 
								 | 
							
								way you can just specify `bash /path/to/script.sh` in the last column of the
							 | 
						||
| 
								 | 
							
								table.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Using stars in all columns is the simplest line of a `cron` table, so let's 
							 | 
						||
| 
								 | 
							
								look at some examples of more complex table entries:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								# m h  dom mon dow   command
							 | 
						||
| 
								 | 
							
								00 * * * * bash /path/to/script.sh     # Runs every hour at the start of the hour
							 | 
						||
| 
								 | 
							
								00 12 * * * bash /path/to/script.sh    # Runs every day at noon
							 | 
						||
| 
								 | 
							
								* 12 * * * bash /path/to/script.sh     # Runs every minute between 12pm and 12:59pm
							 | 
						||
| 
								 | 
							
								00 00 05 * * bash /path/to/script.sh   # Runs the 5th day of every month at midnight
							 | 
						||
| 
								 | 
							
								00 00 * 07 * bash /path/to/script.sh   # Runs every day in the month of July at midnight
							 | 
						||
| 
								 | 
							
								00 00 * * 2 bash /path/to/script.sh    # Runs every Tuesday at midnight
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Besides numbers and the star there are a few other characters that you can use
							 | 
						||
| 
								 | 
							
								in `cron` table columns including a hyphen (`-`) for specifying ranges and a
							 | 
						||
| 
								 | 
							
								comma (`,`) for specifying lists of items. For example `00-29` in the Minutes
							 | 
						||
| 
								 | 
							
								column would specify the first thirty minutes of an hour, while `1,5` in the
							 | 
						||
| 
								 | 
							
								Day of Week column would specify Monday and Friday.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's take a look at another example of a `cron` table that uses hyphens and 
							 | 
						||
| 
								 | 
							
								ranges so you can get a sense of how each character works.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								# m h  dom mon dow   command
							 | 
						||
| 
								 | 
							
								00-04 * * * * bash /path/to/script.sh       # Runs every minute for the first five minutes of every hour
							 | 
						||
| 
								 | 
							
								00 00 * * 0,6 bash /path/to/script.sh       # Runs at midnight every Saturday and Sunday
							 | 
						||
| 
								 | 
							
								00 03 01-15 * * bash /path/to/script.sh     # Runs at 3am for the first fifteen days of every month 
							 | 
						||
| 
								 | 
							
								00,30 * * * * bash /path/to/script.sh       # Runs at the start and middle of every hour
							 | 
						||
| 
								 | 
							
								00 00,12 * * * bash /path/to/script.sh      # Runs every day at midnight and noon
							 | 
						||
| 
								 | 
							
								00 * 01-07 01,06 * bash /path/to/script.sh  # Runs at the start of every hour for the first seven days of the months of January and June
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A program that is being run by `cron` is only as powerful as your imagination
							 | 
						||
| 
								 | 
							
								can stretch! If you're familiar with the social network
							 | 
						||
| 
								 | 
							
								[Twitter](https://twitter.com/) then you might have come across some Twitter
							 | 
						||
| 
								 | 
							
								accounts which create posts automatically like
							 | 
						||
| 
								 | 
							
								[Emoji Aquarium](https://twitter.com/emojiaquarium),
							 | 
						||
| 
								 | 
							
								[Old Fruit Pictures](https://twitter.com/pomological), or
							 | 
						||
| 
								 | 
							
								[Endless Screaming](https://twitter.com/infinite_scream). Many of these "bot"
							 | 
						||
| 
								 | 
							
								accounts are powered by `cron`, which uses Twitter's HTTP API to post tweets
							 | 
						||
| 
								 | 
							
								regularly.
							 |