3

My goal is to back up some markdown notes I keep in my /Users/<me>/codes/notes folder daily. I have a crontab job setup to run every minute to troubleshoot, but eventually I'd like this to be daily.

crontab job

* * * * * cd ~/codes/notes && ./backup_notes.sh

backup_notes.sh

#!/bin/sh

# create a timestamp alias for the commit message
timestamp() {
  date +"%Y-%m-%d @ %T"
}

# Go to my notes folder
cd /Users/<me>/codes/notes

# pull & push
if [[ `git status --porcelain` ]]; then
    git pull origin main
    git add .
    git commit -m "Update: $(timestamp)"
    git push origin main
fi

I believe the script by itself works because I can do:

❯ ./backup_notes.sh

And changes are pushed to the remote repository on github.

I also believe the crontab job is firing because if I add echo "hello world" > ./log.txt to the top of my backup_notes.sh I will get the expected hello world in ./log.txt

I'm pretty stuck and would appreciate it if anyone has any advice on how I can troubleshoot.

Things I've tried:

  • Replace git with /usr/local/bin/git
  • Remove the conditional
  • Double checked chmod 744 ~/codes/notes/backup_notes.sh
  • Added * * * * * cd ~/codes/notes && echo "hello world" > ./log.txt to verify that the crontab was working, and this will put hello world into log.txt.

I've also added some echos:

#!/bin/bash

# create a timestamp alias for the commit message
timestamp() {
  date +"%Y-%m-%d @ %T"
}

# Go to my notes 
cd /Users/jesse.spevack/codes/notes

echo "job started: $(timestamp)" > log.txt

# pull & push
if [[ `git status --porcelain` ]]; then
  echo "Running Git commands: $(timestamp)" >> log.txt
  git pull origin main
  git add .
  git commit -m "Update: $(timestamp)"
  git push origin main
  echo "Finished running Git commands: $(timestamp)" >> log.txt
fi

echo "job done: $(timestamp)" >> log.txt

Which adds the following to my log.txt:

job started: 2021-03-14 @ 09:12:00
Running Git commands: 2021-03-14 @ 09:12:00
Finished running Git commands: 2021-03-14 @ 09:12:01
job done: 2021-03-14 @ 09:12:01

However, there is no affect on the remote repository on github.

Jesse Spevack
  • 113
  • 1
  • 2
  • 6
  • 2
    BTW double bracket notation `[[` is a bashism, so you should change your shebang to bash (though I assume this isn't the root cause since you mentioned it also failed without the conditional). – tdy Mar 14 '21 at 06:30
  • For debugging, try leaving unstaged changes in your repo, then check the repo status after the cronjob fires to see whether those changes are still unstaged, staged, committed, etc. – tdy Mar 14 '21 at 06:38

2 Answers2

2

Run your script under a reduced environment, like

 env -i HOME=$HOME ./backup_notes.sh

You might find that the script should set PATH or some other variable not found in a cron environment. To inspect the (quite limited) cron environment, place set at the beginning of your script.

Jens
  • 69,818
  • 15
  • 125
  • 179
  • I noticed I had `GITHUB_API_TOKEN` set in my shell, but the cron job did not. I've added that to the cron job. Any other env things you think I should look at? – Jesse Spevack Mar 14 '21 at 15:27
  • @JesseSpevack Most commonly PATH must be set to find all utilities. You'll know if you have "command not found: foo" errors. – Jens Mar 14 '21 at 17:26
0

Problem:

A script I wrote was not able to push contents of a git repo to github

Cause:

  1. The script did not have the right path variables
  2. The repo was not setup with an SSH remote

Solution:

  1. Set up path and shell for crontab - How to get CRON to call in the correct PATHs

  2. Set up SSH for the repo in question - git remote set-url origin git@github.com:USERNAME/REPONAME.git see: https://gist.github.com/developius/c81f021eb5c5916013dc

Helpful debugging tips:

  1. Add a log.txt file
  2. Use echo "Some text" > log.txt liberallyh
  3. Capture errors and command outputs by <my command> 2>&1 | tee -a log.txt for exampel git pull origin main 2>&1 | tee -a log.txt
Jesse Spevack
  • 113
  • 1
  • 2
  • 6