- toolbox.sh
#!/usr/bin/env bash
insert_date()
{
while read
do
local date_value
date_value="$(date +"%b %d %T %s.%N")"
echo "${date_value} ${REPLY}"
done
}
fatal_error_handler()
{
local result="$?"
local p_message="$1"
local pid="${BASHPID}"
(exit "${result}") ||
{
(
cd "${BASH_SOURCE[1]%/*}"
echo -n "${FUNCNAME[0]}: $(echo | insert_date)${PWD}/${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]} ${FUNCNAME[1]}() PID(${pid})"
)
[ "${p_message}" != "" ] && echo -n " ${p_message}"
echo
return "${result}"
} >&2
}
execute_with_retry()
{
local p_max_try_count="$1"
shift
false
local result="$?"
local try_number=0
while ((try_number < p_max_try_count))
do
echo "Execute command($@): try #$((try_number+1))/${p_max_try_count}" >&2
"$@" && return
result="$?"
sleep 1
((++try_number))
done
return "${result}"
}
get_own_process_group()
{
local ps_output
ps_output=($(ps --no-heading -o pgrp "$$")) || fatal_error_handler || return
[ "${#ps_output[@]}" = "1" ] || fatal_error_handler || return
echo "${ps_output[0]}"
}
dd_benchmark.sh
- dd_benchmark.sh
#!/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
Utilisation
Mettre les deux fichiers dans le meme repertoire
Executer : dd_benchmark.sh “WRITE” ”/dev/null” ”/tmp/dd_benchmark.log”
Ctrl-C pour interrompre le programme ou attendre que /dev/null soit plein :)