I'm looking to periodically run a script which copies only the most recently edited file over from one directory, over to another one. How do I do this with a shell script on OSX?
1 Answer
The easiest way would be to do this directly through cron
. For example, to copy the file once a week, create a crontab like this:
@weekly cp "$(ls -t /path/to/source | head -1)" /path/to/target
DETAILS:
The -t
flag of ls
means sort by time, so by printing only the first file (head -1
) I know I am getting the newest. Running ls -t /path/to/source | head -1
will return the newest file in the directory /path/to/source
so cp "$(ls -t /path/to/source | head -1)" /path/to/target
will copy the newest file from source
to target
. The quotes around the expression are needed in order to deal with file names that contain spaces.
Wikipedia explains that
Cron is the time-based job scheduler in Unix-like computer operating systems. Cron enables users to schedule jobs (commands or shell scripts) to run periodically at certain times or dates. It is commonly used to automate system maintenance or administration.
[...]
Cron is driven by a crontab (cron table) file, a configuration file that specifies shell commands to run periodically on a given schedule.
To create a new crontab, open a terminal and run
crontab -e
This will launch your default editor ($EDITOR
) and present you with a text file. Paste the line above into that file, save and exit and that's it, your crontab has been created.
The format of crontabs is (taken from here):
* * * * * command to be executed
- - - - -
| | | | |
| | | | +----- day of week (0 - 6) (Sunday=0)
| | | +------- month (1 - 12)
| | +--------- day of month (1 - 31)
| +----------- hour (0 - 23)
+------------- min (0 - 59)
So, for example, to run cp /foo /bar
at 14:35 on October 12th you would write:
35 14 12 11 cp /foo /bar
The cron
daemon also understands some shorthand commands such as:
string meaning
------ -------
@reboot Run once, at startup.
@yearly Run once a year, "0 0 1 1 *".
@annually (same as @yearly)
@monthly Run once a month, "0 0 1 * *".
@weekly Run once a week, "0 0 * * 0".
@daily Run once a day, "0 0 * * *".
@midnight (same as @daily)
@hourly Run once an hour, "0 * * * *".
So, the crontab I gave above means run the cp
command once a week at midnight on Sunday morning.