I'm doing a triathlon for charity! Donate here
Josh Dawson
Modern art makes me want to rock out

Rip CDs Automatically When Inserted with Ubuntu 24 & ABCDE

3 minutes to read

I’ve recently started to buy CDs again. Buying and having physical music is just great. The benefit of the CD being that I can rip it, and still access my purchased music anywhere. Couple that with an unnecessary requirement to automate as much of the process as possible and I wind up writing this for anybody that may fall down the same rabbit hole as I have.

A lot of what inspired this comes from this great blog post that I’ve found but needed to make some changes to.

What you’ll need

  • A Linux device with an optical disc drive (I’m using Ubuntu 24)
  • abcde installed
  • at installed
  • Patience

What we’re trying to achieve

Ideally, I want to insert a CD to the drive of my computer and walk away while it rips to FLAC and drops into my media folder. Bonus points if I can be notified that it’s complete.

The First Script

We need to enlist udev to trigger our main script when a CD is inserted. This is where we find a difference between my script and the one in Winny’s Blog. In newer versions of Linux, the udev environment doesn’t have any internet access, or sudo capabilities. To get around that, you’ll need to leverage at which is a package that schedules commands for execution. I’ve created a script in /etc/udev/rules.d/90-ripper.rules and populated it with the following:

SUBSYSTEM=="block", KERNEL=="sr*", ACTION=="change", RUN+="/bin/bash -c 'echo /usr/local/sbin/rip-music-cd | at now'"

Go ahead and create something similar, then run udevadm control --reload for it to take effect.

The Second Script

Now for the main course. Create a new script in /usr/local/sbin/rip-music-cd (or wherever you like, just make sure the udev script has the same file path) and add this:

#!/bin/bash

RIPUSER=josh

# Define the log file location
LOGFILE="/var/log/abcde_rip.log"

echo "Sleeping to allow warmup" >> $LOGFILE
sleep 5

# Ensure the log file directory exists
mkdir -p "$(dirname "$LOGFILE")"

# Define the CD drive location
CD_DRIVE="/dev/sr0"

# Path to the abcde configuration file
ABCDE_CONF="/home/josh/.abcde.conf"  # Replace with the path to your abcde config

# Set the PATH variable to include common directories
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

# Check if the CD drive contains a disc by using blockdev
if ! blockdev --getsize64 $CD_DRIVE > /dev/null 2>&1; then
    echo "No disc detected in $CD_DRIVE or unable to read the drive. Please insert a CD and try again."
    exit 1
fi

# Inform anyone watching the logs that the disc is detected
echo "Disc detected in $CD_DRIVE. Starting the ripping process..." >> $LOGFILE

# Run abcde in non-interactive mode and log output
abcde -B -G -N -o flac -c '/var/abcde.conf' > "$LOGFILE" 2>&1

# Capture the exit status of abcde
abcde_exit_status=$?

# Check if abcde was successful
if [ $abcde_exit_status -eq 0 ]; then
    # Send the POST request upon successful completion
    echo "Everything completed successfully" >> $LOGFILE
    curl -X POST https://maker.ifttt.com/trigger/jd_cd_complete/json/with/key/XXXXXXXXXXXXX -H "Content-Type: application/json" -d '{"msg": "CD RIP Complete"}' 
else
    echo "abcde encountered an error. Check the log at $LOGFILE for details." >> "$LOGFILE"
fi

Breaking this down, we start with a definition of my user and a 5 second wait period. I found without that I could often beat the CD spinning up.

Defining a log file gives us something to tail while the process is happening if we don’t quite trust it.

We define the CD drive location (found for me with lsblk) and then check if there’s anything in said drive.

Then we perform the ripping process with ABCDE and monitor wait for an exit status. When that’s done, I call out to an IFTTT webhook that sends a push notification to my phone. I receive that, get off my arse and swap another CD into the drive. Job done!

With that, you should be able to insert a CD and watch the magic happen by tailing your log file.