#!/usr/bin/env bash cd "${0%/*}" || exit PATH+=":${PWD}" cd - &> /dev/null source "toolbox.sh" || exit set -o pipefail declare -r g_mode_read="READ" declare -r g_mode_write="WRITE" terminate_process_group() { kill -TERM -"$(get_own_process_group)" } exit_handler() { terminate_process_group } int_handler() { terminate_process_group } child() { local p_mode="$1" local p_file="$2" local p_log_file="$3" if [ "${p_mode}" = "${g_mode_write}" ] then dd if=/dev/zero of="${p_file}" bs=8M 2>&1 | stdbuf -o0 grep 'copied' | insert_date | tee "${p_log_file}" || fatal_error_handler elif [ "${p_mode}" = "${g_mode_read}" ] then dd if="${p_file}" of=/dev/null bs=8M 2>&1 | stdbuf -o0 grep 'copied' | insert_date | tee "${p_log_file}" || fatal_error_handler else fatal_error_handler fi terminate_process_group } get_dd_pid() { local pid_container pid_container=($(pgrep -g "$(get_own_process_group)" dd)) || fatal_error_handler || return [ "${#pid_container[@]}" = "1" ] || fatal_error_handler || return echo "${pid_container[0]}" } main() { local p_mode="$1" local p_file="$2" local p_log_file="$3" trap exit_handler EXIT trap int_handler SIGINT child "${p_mode}" "${p_file}" "${p_log_file}" & local dd_pid execute_with_retry 5 eval 'dd_pid="$(get_dd_pid)"' || fatal_error_handler || return while true do sleep 1 kill -USR1 "${dd_pid}" || fatal_error_handler || return done } LANG="C" main "$@" || fatal_error_handler