Automating Website Creation With Hugo, Bash, and Zshell

A few tools I use to help build my site.

Published: June 14, 2021

Reading Time: 4 minutes

Why automate?

Often times people ask “Why spend time automating things when you spend more time automating than you spend on the actual task?”. My answer to this is simple, it is exponentially easier to get started working on a a task when you know that all you have to do is the task itself. All the little things between point A and B are taken care of ahead of time. This was the issue I was having when it came to writing these blog posts, the actual writing wasn’t the tedious/time consuming part, it was the little tasks in between writing and uploading.

The issue

I was running into multiple issues putting information up onto my site that made it such a headache to maintain that I just stopped updating it. Take a look at some of the terrible formatting I would have to sift through each time I wanted to make a small change to the site.

My old site was just a plain HTML document that required me to manually go in and make changes to the HTML every time I wanted to add/remove/modify any of the content. This was a huge pain and made it nearly impossible to maintain. My solution to find an easier way to manage my content. I started doing some research and came across Hugo. After initially getting Hugo set up, I was not very impressed, but this was mainly because I hadn’t spent enough time figuring out to make Hugo work for me. At this point I had gotten away from editing a static HTML site, but it was still taking way too long to get content up on my site.


I love writing in markdown. To write blogposts I use a program called obsidian which lets me easily write in markdown. In the most meta move ever, here is what the current blogpost looks like so far in obsidian.

I could write a whole novel (in markdown) about why I love writing in markdown, but I will save that for another time. All you need to know right now is that Hugo takes markdown files (like this one) and converts them to a fancy html page. As long as your writing is in markdown, hugo will have no trouble converting it to HTML.

Now I have Hugo problems

Some of the issues I was running into with hugo

  1. I was having an issue with my screenshot tool due to moving to i3
  2. the images I was copy and pasting into my blogs were save with filenames that contained spaces (this was not configurable)
  3. The Images in my blog were being saved to the wrong directory
  4. I was spending time manually creating files and editing all the tags
  5. I was manually moving files to the correct hugo directories and previewing them to make sure nothing broke
  6. I was manually moving stuff over to S3 by dragging it into the web interface

The nice part about these problems was that they were all solvable with scripting. So how did I accomplish that? I decided to list every part of the process between writing a blog post and actually having it live on my website. This is what that list looked like. c

  • Fix flameshot delay issue (issue is with notification daemon)
  • Set up template for tags in obsidian
  • Write bash script to
    • rename all images in the current blog to use hyphens instead of spaces
    • move all pasted images to /static folder so hugo knows where to find them
    • move to content/blog/name_of_blog_post
    • generate the final output for previewing in firefox
    • run hugo preview command
  • Make zsh alias ‘uploadwebsite’ that uses AWS CLI to upload site to S3

After a few hours of tinkering, I was able to solve all of these problems in a quick and very dirty bash script.

if [ $# -eq 0 ]; then
    echo "enter path to blogpost as argument"
    exit 1
# Rename files in attachments
cp $1/attachments/* static/ 
cd static/
# For each file with a space in it, change it to a -
for f in *
  new="${f// /-}"
  if [ "$new" != "$f" ]
    if [ -e "$new" ]
      echo not renaming \""$f"\" because \""$new"\" already exists
      echo moving "$f" to "$new"
    mv "$f" "$new"

# Go back to hugo folder
cd /path/to/my/site/
# Copy all markdown files to content/blog
cp $1/*.md content/blog/
# Regex
sed -i 's/\[\](P/\[\](\/P/' content/blog/*.md 
sed -i 's/-/-/g' content/blog/*.md 
echo "copied $1 to the correct folders"
# Start preview
hugo server -D

Once that script is ran and I am happy with the preview, I can simply type uploadwebsite to run the zshell alias I made which takes uploadwebsite and turns it into-> hugo; aws s3 cp /path/to/hugo/public/ s3://mys3bucketname --recursive

The final Result

This is the final result. Before I moved to hugo and did some quick automating, it would take about an hour to add a resource to my website. Now it only takes a few seconds

Contact me

Twitter: @grahamhelton3

LinkedIn: Graham Helton

Discord Server: