A Complex Cron Entry Explained
A crontab entry I felt worth explanation, as it illustrates a few Unix concepts:
$ crontab -l
# m h dom mon dow command
*/5 8-18 * * mon-fri grep -q open /proc/acpi/button/lid/LID0/state && mkdir -p /home/djh/Dropbox/webcam/`date +%Y%m%d` && fswebcam -q -d /dev/video0 -r 1920x1080 /home/djh/Dropbox/webcam/%Y%m%d/%H%M.jpg ; file /home/djh/Dropbox/webcam/`date +%Y%m%d/%H%M`.jpg | grep -q 1920x1080 || fswebcam -q -d /dev/video1 -r 1920x1080 /home/djh/Dropbox/webcam/%Y%m%d/%H%M.jpg
That is a huge gob of text. Let me un-pack that into parts:
*/5 8-18 * * mon-fri
Run weekdays, 8AM to 6PM, every five minutes.
grep -q open /proc/acpi/button/lid/LID0/state &&
mkdir -p /home/djh/Dropbox/webcam/`date +%Y%m%d` &&
fswebcam -q -d /dev/video0 -r 1920x1080 /home/djh/Dropbox/webcam/%Y%m%d/%H%M.jpg
Check if the lid on the computer is open by looking for the word “open” in /proc/acpi/button/lid/LID0/state
AND
(… if the lid is open) make a directory with today’s date AND
(… if the directory was made) take a timestamped snapshot from the web cam and put it in that folder.
Breaking it down a bit more:
grep -q
means grep “quietly” … we don’t need to print that the lid is open, we care about the return code. Here is an illustration:
$ while true; do grep open /proc/acpi/button/lid/LID0/state ; echo $? ; sleep 1; done
state: open
0
state: open
0
# Lid gets shut
1
1
# Lid gets opened
state: open
0
state: open
0
The $? is the “return code” from the grep command. In shell, zero means true and non-zero means false, that allows us to conveniently construct conditional commands. Like so:
$ while true; do grep -q open /proc/acpi/button/lid/LID0/state && echo "open lid: take a picture" || echo "shut lid: take no picture" ; sleep 1; done
open lid: take a picture
open lid: take a picture
shut lid: take no picture
shut lid: take no picture
open lid: take a picture
open lid: take a picture
There is some juju in making the directory:
mkdir -p /home/djh/Dropbox/webcam/`date +%Y%m%d`
First is the -p
flag. That would make every part of the path, if needed (Dropbox .. webcam ..) but it also makes mkdir
chill if the directory already exist:
$ mkdir /tmp ; echo $?
mkdir: cannot create directory ‘/tmp’: File exists
1
$ mkdir -p /tmp ; echo $?
0
Then there is the backtick substitition. The date command can format output (read man date
and man strftime
…) You can use the backtick substitution to stuff the output of one command into the input of another command.
$ date +%A
Monday
$ echo "Today is `date +%A`"
Today is Monday
Once again, from the top:
grep -q open /proc/acpi/button/lid/LID0/state &&
mkdir -p /home/djh/Dropbox/webcam/`date +%Y%m%d` &&
fswebcam -q -d /dev/video0 -r 1920x1080 /home/djh/Dropbox/webcam/%Y%m%d/%H%M.jpg ;
file /home/djh/Dropbox/webcam/`date +%Y%m%d/%H%M`.jpg | grep -q 1920x1080 ||
fswebcam -q -d /dev/video1 -r 1920x1080 /home/djh/Dropbox/webcam/%Y%m%d/%H%M.jpg
Here is where it gets involved. There are two cameras on this mobile workstation. One is the internal camera, which can do 720 pixels, and there is an external camera, which can do 1080. I want to use the external camera, but there is no consistency for the device name. (The external device is video0 if it is present at boot, else it is video1.)
Originally, I wanted to do like so:
fswebcam -q -d /dev/video0 -r 1920x1080 || fswebcam -q -d /dev/video1 -r 1920x1080
Unfortunately, fswebcam
is a real trooper: if it can not take a picture at 1920×1080, it will take what picture it can and output that. This is why the whole cron entry reads as:
Check if the lid on the computer is open AND
(… if the lid is open) make a directory with today’s date AND
(… if the directory was made) take a timestamped snapshot from web cam 0
Check if the timestamped snapshot is 1920×1080 ELSE
(… if the snapshot is not 1920×1080) take a timestamped snapshot from web cam 1
Why am I taking these snapshots? I do not really know what I might do with them until I have them. Modern algorithms could analyze “time spent at workstation” and give feedback on posture, maybe identify “mood” and correlate that over time … we’ll see.
OR not.