Hero Image
- Philipp Ludewig

Usage of Crontab in MacOS


some days ago I had one of this moments. You execute a command you shouldn't have executed and then two years of my bash history gone forever. I was devasteded and i subconciusly answered the question to which group of people i belong to: the one who didn't made a backup. You bet this was my reaction:

Let's create a backup and automate that process! I will use bash scripts and the good old cron. Don't use vim to edit the crontab and use nano for that instead. Spacevim will throw an error if you use vim to edit the crontab and you can only resolve this by terminating the terminal session.

export EDITOR=/usr/bin/nano
crontab -e

My crontab look like this:

0 12 * * 3  cd ~/backupZSH/ && ./backupHistory.sh >/tmp/stdout.log 2>/tmp/stderr.log
0 10 * * 1-5  cd ~/git/ && ./pullRebaseAllRepos.sh >/tmp/stdout.log 2>/tmp/stderr.log

The first command will backup my beautiful history and the second one will rebase all my git repositorues so i don't have to do it. Let's have a look at the start of the cron command. The five asterics define the point in time where the command will be executed. Below you can read about the definition or more here

* * * * *  command to execute
│ │ │ │ │
│ │ │ │ └─── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
│ │ │ └──────── month (1 - 12)
│ │ └───────────── day of month (1 - 31)
│ └────────────────── hour (0 - 23)
└─────────────────────── min (0 - 59)

Then you also get some mail which you can access by writing "mail" in your shell. After you looked into the mail you simply leave the process with 'q'. As you can see i have also added ">/tmp/stdout.log 2>/tmp/stderr.log" after the execution of the shell scripts in order to create logs for the processes. Now to the scripts. I found these script on git and modified it so the ssh-key identities are added to the subshell where this cron-job will run.


# store the current dir

# Let the person running the script know what's going on.
echo -e "\n\033[1mPulling in latest changes for all repositories...\033[0m\n"
# We need to import the ssh keys
    eval "$(ssh-agent -s)";
    ssh-add  ~/.ssh/id_rsa;

# Find all git repositories and update it to the master latest revision
for i in $(find . -name ".git" | cut -c 3-); do
    echo "";
    echo -e "\033[33m"+$i+"\033[0m";

    # We have to go to the .git parent directory to call the pull command
    cd "$i";
    cd ..;

      # finally pull rebase
    git pull -r origin master;

    # lets get back to the CUR_DIR
    cd $CUR_DIR

echo -e "\n\033[32mComplete!\033[0m\n"

In the second script i simply copy the history to another folder. This is a simple solution where i can worry about uploading the files to another storage device later.

#!/usr/bin/env bash

current_date=`date +"%Y_%d_%m"`

cp ~/.zsh_history ~/backupZSH/${name}

That's it, first simple backup solution done. :)


If you would need to edit your shells history may it be bash or zsh then simply go into a different shell with for example exec sh and then edit the history file there.