Raspberry Pi online course

Create a Raspberry Pi Camera Script That Saves Timestamped Photos

Learn how to create, make executable, and run a Bash script on Raspberry Pi OS that captures a JPEG photo with a timestamped filename.

What the camera script does

A camera capture script packages several terminal instructions into one repeatable command. Instead of typing a camera command and filename each time, you run one Bash script that captures a still image and saves it in a known directory.

Bash is a Unix shell and scripting language used to run commands and automate tasks. This lesson uses Bash to prepare a filename, call the Raspberry Pi camera program, and save a JPEG image.

Each filename contains a timestamp: a date-and-time value identifying when the photo was captured. Timestamp-based names make ordinary captures distinct instead of repeatedly saving over one file.

  1. Prepare a destination directory.
  2. Create the Bash script.
  3. Grant the script execute permission.
  4. Run the script.
  5. Verify the saved JPEG and its timestamped filename.

This lesson captures one still photograph at a time. It does not configure video recording, time-lapse capture, or scheduled automation.

Prerequisites and camera readiness

You need a Raspberry Pi running Raspberry Pi OS or an older Raspbian installation, a supported Raspberry Pi Camera connected to the camera connector, and access to a terminal. The camera should be physically connected in the correct orientation and available to the operating system.

Test the camera with the still-image command installed on your system before debugging the script. A script cannot fix a loose ribbon cable, a disabled camera, missing camera software, or another program that is already using the camera. For background on enabling the camera on older systems, see Enable Camera In Raspi Config.

Camera command names depend on the operating-system release and camera stack:

Operating System or Camera StackStill Image CommandNotes

Older Raspbian legacy stackraspistill — Legacy command for taking still photographs.

Raspberry Pi OS using libcamera toolslibcamera-still — Used by many newer Raspberry Pi OS releases.

Recent Raspberry Pi OS using rpicam toolsrpicam-still — Newer naming for the Raspberry Pi still-capture command.

Check which command is available before choosing the script version:

command -v raspistill
command -v libcamera-still
command -v rpicam-still

Use the command that returns a path. If none is found, install or enable the camera tools appropriate for your Raspberry Pi OS release before continuing.

Create a photo storage directory

A directory is a folder in the filesystem. Use mkdir, the command for creating a directory, to create a folder for captured images:

mkdir -p /home/pi/pics

The -p option creates missing parent directories without reporting an error if the directory already exists. The path is an absolute path: a complete filesystem location beginning at the root directory, /. Using an absolute output path means the script saves photos in /home/pi/pics even when you launch it from another directory.

The example assumes the user account is named pi. If your account has another name, replace /home/pi with your actual home directory. The account running the script must own the directory or have permission to write to it.

Confirm that the directory exists and inspect its permissions:

ls -ld /home/pi/pics

Create the Bash script

Use nano, a terminal-based text editor, to create the script:

nano /home/pi/take-picture.sh

Enter a script matching the camera command available on your system. This is a legacy raspistill example:

#!/bin/bash
DATE=$(date +%Y-%m-%d_%H%M%S)
raspistill -vf -hf -o /home/pi/pics/$DATE.jpg

The first line is the shebang. A shebang identifies the interpreter used to run a script; #!/bin/bash tells the system to use Bash.

The second line runs date, which returns the system date and time, and stores the formatted result in the shell variable DATE. The format uses year, month, day, hour, minute, and second. Underscores and hyphens are safe, readable filename characters.

The final line calls raspistill. Its -o option selects the output JPEG filename. The complete output path is:

/home/pi/pics/$DATE.jpg

When Bash expands $DATE, a filename might look like 2026-08-18_143205.jpg.

Using the current camera command

On a system that provides rpicam-still, use this version instead:

#!/bin/bash
DATE=$(date +%Y-%m-%d_%H%M%S)
rpicam-still -o /home/pi/pics/$DATE.jpg

If your installation provides libcamera-still, replace rpicam-still with libcamera-still:

#!/bin/bash
DATE=$(date +%Y-%m-%d_%H%M%S)
libcamera-still -o /home/pi/pics/$DATE.jpg

Camera orientation options differ between the legacy and newer camera tools. Do not assume that -vf and -hf have the same meaning or syntax in every command.

Understand the script components

ComponentRoleExample

Shebang — Identifies the script interpreter. — #!/bin/bash

Timestamp variable — Stores a filesystem-safe date and time. — DATE=$(date +%Y-%m-%d_%H%M%S)

Output directory — Defines where the image is stored. — /home/pi/pics

Camera command — Captures one still image. — rpicam-still

Output option — Selects the destination filename. — -o /home/pi/pics/$DATE.jpg

Output extension — Identifies the image as a JPEG. — .jpg

Execute permission — Allows direct launching of the file. — chmod +x

Timestamp filenames and collisions

The format %Y-%m-%d_%H%M includes the year, month, day, hour, and minute:

DATE=$(date +%Y-%m-%d_%H%M)

This matches a minute-level naming scheme such as 2026-08-18_1432.jpg. It is easy to read and prevents captures made in different minutes from overwriting each other.

However, two captures made within the same minute receive the same name. The second capture can overwrite the first, depending on the camera command's behavior. For repeated or rapid captures, include seconds as shown in the main examples:

DATE=$(date +%Y-%m-%d_%H%M%S)

If multiple captures can occur within the same second, add another unique suffix, such as a counter or a process-specific value.

Save and make the script executable

In nano, save the file by pressing Ctrl+O, confirm the filename, and press Enter. Exit nano with Ctrl+X.

Use chmod +x to add executable permission:

chmod +x /home/pi/take-picture.sh

Executable permission allows the operating system to launch a file as a program. The script can still be read without this permission, but a direct launch may fail with “Permission denied.”

Inspect the permissions with:

ls -l /home/pi/take-picture.sh

Look for an x in the permission listing, for example -rwxr-xr-x. If it is missing, run chmod +x again. For more terminal fundamentals, see Terminal In Raspbian and Useful Terminal Commands.

Run and verify the script

Run the script using its full path:

/home/pi/take-picture.sh

You can also change to the script's directory and use ./. The prefix tells the shell to run the file in the current directory:

cd /home/pi
./take-picture.sh

After the camera finishes, list the photo directory:

ls -l /home/pi/pics

Confirm that a file ending in .jpg appears, that it is stored in the intended directory, and that its name matches the current date and time. Because the script uses an absolute output path, its saved image location does not depend on the directory from which you ran it.

StepActionCommand or ToolExpected Result

Create image directory — Make the destination folder. — mkdir -p — The pics directory exists.

Create script — Open a new Bash file. — nano — The script opens for editing.

Add timestamp and camera command — Generate a name and capture one image. — date and the installed still command — The script contains the capture instructions.

Save the file — Write the script to disk. — Nano save command — take-picture.sh exists.

Set execute permission — Allow direct launching. — chmod +x — The permission listing includes x.

Run script — Capture a photograph. — Full path or ./take-picture.sh — The camera takes one still image.

Check captured JPEG — Verify the result. — ls -l /home/pi/pics — A timestamped JPEG appears.

Run the script from the graphical desktop

You can also launch the script through the Raspberry Pi OS file manager:

  1. Browse to the script in the file manager, such as /home/pi/take-picture.sh.
  2. Double-click the file.
  3. When prompted, choose the execute or run action rather than opening the file as text.
  4. Check the photo folder for the new JPEG.

Desktop behavior depends on Raspberry Pi OS file-manager settings. Some configurations open executable text files in an editor or ask what action to take. The script must have executable permission, and the file manager must be configured to allow execution.

Troubleshooting

“Permission denied”

Run chmod +x /home/pi/take-picture.sh, then launch it with /home/pi/take-picture.sh or ./take-picture.sh from its directory. Inspect the permissions with ls -l.

“Command not found”

The script may use raspistill on a newer installation that provides libcamera-still or rpicam-still instead. Run the three command -v checks, then use the installed command. If no command is available, install or enable the applicable camera tools for the operating system.

No image appears in the folder

Recreate the directory with mkdir -p /home/pi/pics. Check the absolute output path, directory ownership, and write permissions. Run the camera command manually so its error output is visible:

rpicam-still -o /home/pi/pics/test.jpg

Replace rpicam-still with libcamera-still or raspistill as appropriate.

The camera fails to capture

Check the ribbon cable and camera-module orientation. Test the installed still-image command outside the script. Also close other applications that may already be using the camera.

The photo is mirrored or upside down

Legacy raspistill supports -hf for a horizontal flip and -vf for a vertical flip. A horizontal flip mirrors the image left to right; a vertical flip reverses its top and bottom. Remove or adjust these options when the physical camera mounting does not require them. Orientation syntax may differ for libcamera-still and rpicam-still.

A capture overwrites an earlier photo

The filename may record only the date, hour, and minute. Add seconds with %S, or add another unique suffix if captures can happen within the same second.

Double-clicking does not run the script

Set executable permission, choose the execute option when prompted, and review the file-manager preference for executable text files. Running the script from a terminal is a reliable way to see error messages.