I have a Raspberry Pi that’s been sitting around for some time. And I also have a camera but only 2 16GB cards, so I might run out of space if the shoot gets really long. The obvious choice is to buy more cards, but why not put the Raspberry Pi to use here? I already have a power bank, an SD card reader and a 32GB flash drive so nothing really needed to buy here.

In the field, I also use a Lightning to USB 3.0 adapter to pull the images straight from the camera’s USB port. While Apple never mentioned this, you can also import from USB drives if they follow the DCF standard, which means there is a DCIM folder in the root of the drive and subfolders containing 8 characters (starting with 3 numbers), in which our photos to be imported (also have to have 8-character filenames) have to reside. The downside is that you’ll need to connect the adapter’s Lightning port to a power source when you want to use any USB device that uses the iPhone’s battery to run. On an iPad, you can even use the adapter with a 2.5″ enclosure with a spinning drive inside. Not sure why Apple never allows iPhones to connect to this enclosure even when using the same power adapter…

We can just make the Raspberry Pi copy to whatever directory structure we want, but for this case I’d prefer it conform to the DCF standard so I can import photos from this external drive to my iPhone or even other Android devices that support USB OTG and have the right adapter. With that out of the way, let’s get started:

First of all we need to set a rule for which USB port on the Raspberry Pi is for the card reader and which is for the external drive. For my own case, I’d make the top right USB port on the Raspberry Pi to be the port for the card reader, and the bottom left for the external drive. Then we’ll make the mount points for each – let’s make it /mnt/sda1 for the card reader and /mnt/sdb1 for the external drive.

sudo mkdir -p /mnt/sda1 /mnt/sdb1

Now we will need to find out the disk device path for both USB ports. Plug one of the 2 drives into its corresponding USB port and check in /dev/disk/by-path/ :

sudo ls -lh /dev/disk/by-path/*

You should see an entry for the drive plugged in that ends with sda1/. Note down the full path – on my own Raspberry Pi 2 it’s /dev/disk/by-path/platform-3f980000.usb-usb-0:1.4:1.0-scsi-0:0:0:0-part1 for the top right USB port. Unplug the drive and do the same for the other USB port. Next, we’re going to add these disk device paths to /etc/fstab so that the operating system will mount them to the mount points we want:

sudo nano /etc/fstab

Then add these 2 lines at the very bottom, changing the disk device paths to your own ones. (The sda1 line is the card reader, and the sdb1 line is for the external drive, remember?)

/dev/disk/by-path/platform-3f980000.usb-usb-0:1.4:1.0-scsi-0:0:0:0-part1	/mnt/sda1	vfat	auto,user,rw,uid=1000,gid=1000,utf8,dmask=027,fmask=137,nofail    0	3
/dev/disk/by-path/platform-3f980000.usb-usb-0:1.3:1.0-scsi-0:0:0:0-part1	/mnt/sdb1	vfat	auto,user,rw,uid=1000,gid=1000,utf8,dmask=027,fmask=137,nofail	0	4

When you’re done, press Ctrl+O and Enter to save, then press Ctrl-X to close the text editor. Now connect both the card reader and the external drive to their corresponding ports, then mount them:

sudo mount -a

You should be able to cd to both mount points and see the contents (make sure you don’t mix up sda1 and sdb1!) In case any of your drives is exFAT, install fuse-exfat and exfat-utils then try mounting again:

sudo apt-get update
sudo apt-get install -y fuse-exfat exfat-utils

If the external drive is NTFS, you might need to install ntfs-3g and change the /etc/fstab entry for it from vfat to ntfs-3g. The disk device path might have to be changed to a more specific one, especially /dev/disk/by-uuid/ or LABEL=”” (this LABEL is the name of the NTFS partition).

sudo apt-get update
sudo apt-get install -y ntfs-3g

Once you are certain you can mount them to the right mount points, it’s time to run the script. You can save it anywhere, but for this example we’ll save it to /root/copyonstartup.sh :

sudo nano /root/copyonstartup.sh

Paste the following content into the text editor, changing the mount points for CARD and DRIVE at the top to the mount points you’ve made in the beginning:

#!/bin/bash

CARD=/mnt/sda1
DRIVE=/mnt/sdb1

mount -a
if [ $(mount | grep -c $CARD) = 1 ]; then #Check if card is mounted
	if [ $(mount | grep -c $DRIVE) = 1 ]; then #Check if drive is mounted
		#Check if drive has DCIM, if not create one
		if [ -d $DRIVE/DCIM ]; then mkdir $DRIVE/DCIM; fi
		#Check if drive has existing folders inside DCIM
		if [ `ls $DRIVE/DCIM | grep 100RP | wc -l` == 0 ]; then
			mkdir -p $DRIVE/DCIM/100RP001
			rsync -r $CARD/DCIM/*/ $DRIVE/DCIM/100RP001/
		else
			DIRNUM=$(ls $DRIVE/DCIM | tail -n 1 | tail -c 4) #Get last 3 characters from the last dir in drive/DCIM
			DIRNUM=$((DIRNUM + 1)) #Increment dirnum
			DIRNUM=$(printf "%03d" $DIRNUM) #Pad dirnum
			mkdir -p $DRIVE/DCIM/100RP$DIRNUM
			rsync -r $CARD/DCIM/*/ $DRIVE/DCIM/100RP$DIRNUM/
		fi
	fi
fi

umount -a
poweroff -p

Again, press Ctrl+O and Enter to save, then press Ctrl-X to close the text editor. To make it run as a script, we’ll need to make it executable:

sudo chmod +x /root/copyonstartup.sh

This script will shutdown the Raspberry Pi when it’s done, as we don’t really use a display in the field. Every time you run it, it will:

  1. Mount all drives specified in /etc/fstab. If either the card or the external drive is not mounted, exit the script. You can use the Raspberry Pi normally if either or both drives are not connected at boot time.
  2. If there is no DCIM folder in the external drive, create it.
  3. If there is no subfolder in the external drive’s DCIM folder containing 100RP name, create a new one 100RP001.
  4. If there is already a subdirectory in the external drive’s DCIM folder contains 100RP name, create a new one with the last 3 digits incremented by 1.
  5. Copy from card to the external drive and shutdown when completed.

It’s time to test if it works! Take some photos with a camera using the card, connect both the card (through a card reader) and the external drive to the Raspberry Pi, then run the script:

sudo /root/copyonstartup.sh

If all goes well, the Raspberry Pi will shutdown itself when finished (you can watch the activity LEDs) and the files will be copied from the card reader to the external drive. After you’ve verified that it works, we can run the script every startup with crontab:

sudo crontab -e

Add a line to the bottom, changing the path of the script to your own:

@reboot /root/copyonstartup.sh

Again, press Ctrl+O and Enter to save, then press Ctrl-X to close the text editor. This script is flexible in that you can use any card reader and any type of memory card supported by Linux, and the external drive can be either FAT32 or exFAT (NTFS drives might need to be more specific), just make sure to connect to the right USB ports. If you want to use spinning drives with the Raspberry Pi, your power supply has to be at least 2A and you need to add max_usb_current=1 to the file /boot/config.txt . As expected, speed is not that great because of shared USB 2.0 bandwidth. 

This is the end of the guide on how to make a Raspberry Pi copy from card reader to external drive on startup automatically.

Leave a Reply

Your email address will not be published. Required fields are marked *