ARM, linux, OYB software, shell

Safely flash SD card images with ddsd

I would like to share another wrapper based on the pv command ( because we love progress bars!! ).

As part of my work in NextCloudPi, I am constantly copying images to an SD card to test the latest build. The classic Linux way of doing this is by using the dd command

# dd bs=4M if=NextCloudPi_02-06-18.img of=/dev/sdd && sync

We all know the caveats of using this command, namely

  • The syntax is ugly
  • Better not forget that last sync call
  • There is no safety check to prevent you to mistakenly overwriting your root partition
  • If the SD card showed up in a different place, let’s say /dev/sde, you end up with a new 4GB file in /dev/sdd, and still you think that the copy went well.
  • Even though we now have status=progress for dd, I still like the progress bar better.


The usage is simple

$ ddsd --help
Usage: ddsd (-b/--block-size <block size>) <img_file> <block_device>

The only optional argument is the block size. For instance

# ddsd -b4M NextCloudPi_02-06-18.img /dev/sdc

As in the dd command, the optimum value for this parameter depends on the specifics of the operating system, buffers and hardware. If not specified, the following rule will be used ( from man pv )

The default buffer size is the block size of the input file’s filesystem multiplied by 32 (512KiB max), or 400KiB if the block size cannot be determined.


Get the script and make it executable. You can do this in two lines, but better inspect it first. Don’t trust anyone blindly.

sudo wget -O /usr/local/bin/ddsd
sudo chmod +x /usr/local/bin/ddsd



# pv wrapper to safely flash images to an SD card
# Copyleft 2017 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
# GPL licensed (see end of file) * Use at your own risk!
# Usage:
#   ddsd (-b <block size>) <img_file> <block_device>
# More details at

print_usage() { echo "Usage: $0 (-b/--block-size <block size>) <img_file> <block_device>"; }

  # parse arguments
  local OPTS
  OPTS=$( getopt -o hb: -l block-size: -l help -- "$@" 2>/dev/null )
  [[ $? -ne 0 ]] && { echo "error parsing arguments"; return 1; }
  eval set -- "$OPTS"

  while true; do
    case "$1" in
      -h|--help      ) print_usage; return 0 ;;
      -b|--block-size) local BS=$2; shift 2  ;;
      --)                    shift; break    ;;

  # block size argument
  [[ "$BS" != "" ]] && local ARG="-B $BS"

  local IF="$1"
  local OF="$2"

  # checks
  type pv &>/dev/null || { echo "install pv first"     ; return 1; }
  [[ $# -ne 2 ]] && { print_usage                     ; return 1; }
  [[ -f "$IF" ]] || { echo "$IF does not exist"       ; return 1; }
  [[ -e "$OF" ]] || { echo "$OF does not exist"       ; return 1; }
  [[ -b "$OF" ]] || { echo "$OF is not a block device"; return 1; }
  awk '{ print $1 }' /proc/mounts | grep -q "$OF" && { echo "$OF is currently mounted"; return 1; }

  # CTRL-C trap
  cancel() { echo "cancelling..."; kill $PID; wait $PID; exit 1; }
  trap cancel SIGINT

  # flashing
  echo "flashing..."
  pv $ARG "$IF" > "$OF" &
  wait $PID || return 1
  # syncing
  echo -n "syncing... " && sync && echo "done"

ddsd $@

# License
# This script is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this script; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA  02111-1307  USA

Author: nachoparker

Humbly sharing things that I find useful [ github dockerhub ]


  1. Hi nachoparker,
    looks like a nice script to increase the usability for building a SD cards.
    But I think in your description is a typo: Under Usages the second code blocks calls for the normal >>dd<>ddsd<< instead.
    This can be a frustration trap for users.
    Nevertheless, Thanks for the script!

  2. Hi there.

    Very good job.

    I think there’s a typo in the first installation line, possibly must en in ddsd:
    -O /usr/local/bin/ddsd


  3. What’s that nice terminal theme, that displays you the next tab completion with dimmed colors and the other swag? 🙂

Leave a Reply

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