#!/bin/sh -x fail() { if [ -n "$*" ]; then echo "$*" fi exit 1 } get_fs_details() { df --block-size 1 "${1}" | \ while read device size used available use_pct mounted_on do echo "#${mount_point}# #${mounted_on}#" if [ "${mount_point}" = "${mounted_on}" ]; then echo "fs_size=${size} fs_device=${device}" break fi done } mount_point="${1%%/}" dest_dir="${2}" test -z "${mount_point}" && fail "Usage: ${0} mount_point destination_directory" test -z "${dest_dir}" && fail "Usage: ${0} mount_point destination_directory" test -d "${mount_point}" || fail "Error: mount point ${mount_point} does not exist or is not a directory." test -d "${dest_dir}" || fail "Error: destination ${dest_dir} does not exist or is not a directory." eval "$(get_fs_details "${mount_point}")" test -z "${fs_size}" && fail "Error: failed to determine filesystem size for ${mount_point}." test -z "${fs_device}" && fail "Error: failed to determine device for ${mount_point}." if ! cd "${dest_dir}"; then fail "Error: failed to change directory to ${dest_dir}" fi # Try various unpacking commands, exiting as soon as one of them is successful. # Note that we need to silence dd error, as it will always fail when running out of data. if (dd if="${fs_device}" skip="${fs_size}" bs=1; true) | tar xzf -; then exit 0 fi if (dd if="${fs_device}" skip="${fs_size}" bs=1; true) | tar xjf -; then exit 0 fi fail "Error: failed to extract additional data."