docs: add bash progress bar article
This commit is contained in:
parent
d73dd9d0fa
commit
97b9cb24ad
14 changed files with 1160 additions and 0 deletions
18
content/articles/2024/bash_printf/files/script1_ping.sh
Normal file
18
content/articles/2024/bash_printf/files/script1_ping.sh
Normal file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
PING_ITER=16
|
||||
|
||||
# shellcheck disable=2317
|
||||
command() {
|
||||
local -r host=${1?"first parameter must be an host"}
|
||||
local -r iteration=${2?"second parameter must be an iteration number"}
|
||||
local -r cmd=(ping -c "${iteration}" "${host}")
|
||||
|
||||
"${cmd[@]}"
|
||||
}
|
||||
|
||||
main() {
|
||||
command "aquilenet.fr" "$PING_ITER"
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
24
content/articles/2024/bash_printf/files/script2_getoutput.sh
Normal file
24
content/articles/2024/bash_printf/files/script2_getoutput.sh
Normal file
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env bash
|
||||
PING_ITER=16
|
||||
|
||||
# shellcheck disable=2317
|
||||
command() {
|
||||
local -r host=${1?"first parameter must be an host"}
|
||||
local -r iteration=${2?"second parameter must be an iteration number"}
|
||||
local -r cmd=(ping -c "${iteration}" "${host}")
|
||||
|
||||
"${cmd[@]}"
|
||||
}
|
||||
|
||||
parse_output() {
|
||||
while read -r line; do
|
||||
printf "out: %s\n" "${line}"
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
command "aquilenet.fr" "$PING_ITER" > >(parse_output)
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
29
content/articles/2024/bash_printf/files/script3_rematch.sh
Normal file
29
content/articles/2024/bash_printf/files/script3_rematch.sh
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env bash
|
||||
PING_ITER=16
|
||||
|
||||
# shellcheck disable=2317
|
||||
command() {
|
||||
local -r host=${1?"first parameter must be an host"}
|
||||
local -r iteration=${2?"second parameter must be an iteration number"}
|
||||
local -r cmd=(ping -c "${iteration}" "${host}")
|
||||
|
||||
"${cmd[@]}"
|
||||
}
|
||||
|
||||
parse_output() {
|
||||
while read -r line; do
|
||||
if [[ "$line" =~ icmp_seq=([[:digit:]]{1,}).*time=(.*) ]]; then
|
||||
printf "séquence: %s sur %s temps:%s\n" \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER" \
|
||||
"${BASH_REMATCH[2]}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
command "aquilenet.fr" "$PING_ITER" > >(parse_output)
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
42
content/articles/2024/bash_printf/files/script4_progress.sh
Normal file
42
content/articles/2024/bash_printf/files/script4_progress.sh
Normal file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env bash
|
||||
# shellcheck disable=2317
|
||||
PING_ITER=16
|
||||
PROGRESS_BAR_CHAR=(█ ▒)
|
||||
|
||||
command() {
|
||||
local -r host=${1?"first parameter must be an host"}
|
||||
local -r iteration=${2?"second parameter must be an iteration number"}
|
||||
local -r cmd=(ping -c "${iteration}" "${host}")
|
||||
|
||||
"${cmd[@]}"
|
||||
}
|
||||
|
||||
draw_progressbar() {
|
||||
local -r progress=${1?"progress is mandatory"}
|
||||
local -r total=${2?"total is mandatory"}
|
||||
local progress_segment
|
||||
local todo_segment
|
||||
|
||||
printf -v progress_segment "%${progress}s" ""
|
||||
printf -v todo_segment "%$((total - progress))s" ""
|
||||
printf >&2 "%s%s\r" \
|
||||
"${progress_segment// /${PROGRESS_BAR_CHAR[0]}}" \
|
||||
"${todo_segment// /${PROGRESS_BAR_CHAR[1]}}"
|
||||
|
||||
}
|
||||
|
||||
parse_output() {
|
||||
while read -r line; do
|
||||
if [[ "$line" =~ icmp_seq=([[:digit:]]{1,}).*time=(.*) ]]; then
|
||||
draw_progressbar "${BASH_REMATCH[1]}" "$PING_ITER"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
command "aquilenet.fr" "$PING_ITER" > >(parse_output)
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
||||
# [...]
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env bash
|
||||
# shellcheck disable=2317
|
||||
PING_ITER=16
|
||||
PROGRESS_BAR_CHAR=(█ ▒)
|
||||
|
||||
command() {
|
||||
local -r host=${1?"first parameter must be an host"}
|
||||
local -r iteration=${2?"second parameter must be an iteration number"}
|
||||
local -r cmd=(ping -c "${iteration}" "${host}")
|
||||
|
||||
"${cmd[@]}"
|
||||
}
|
||||
|
||||
draw_progressbar() {
|
||||
local -r progress=${1?"progress is mandatory"}
|
||||
local -r total=${2?"Total elements is mandatory"}
|
||||
local -r info_segment=${3:""}
|
||||
local progress_segment
|
||||
local todo_segment
|
||||
|
||||
printf -v progress_segment "%${progress}s" ""
|
||||
printf -v todo_segment "%$((total - progress))s" ""
|
||||
printf >&2 "%s%s%s\r" \
|
||||
"${info_segment}" \
|
||||
"${progress_segment// /${PROGRESS_BAR_CHAR[0]}}" \
|
||||
"${todo_segment// /${PROGRESS_BAR_CHAR[1]}}"
|
||||
|
||||
}
|
||||
|
||||
parse_output() {
|
||||
while read -r line; do
|
||||
if [[ "$line" =~ icmp_seq=([[:digit:]]{1,}).*time=(.*) ]]; then
|
||||
draw_progressbar \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER" \
|
||||
"Ping in progress (time: ${BASH_REMATCH[2]}) "
|
||||
elif [[ "$line" =~ ^PING(.*\(.*\)).* ]]; then
|
||||
printf "Launch ping command to %s with %d iterations\n" \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER"
|
||||
elif [[ "$line" =~ .*packets\ transmitted.* ]]; then
|
||||
printf "%s\n" "$line"
|
||||
fi
|
||||
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
command "aquilenet.fr" "$PING_ITER" > >(parse_output)
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/env bash
|
||||
# shellcheck disable=2317
|
||||
PING_ITER=16
|
||||
PROGRESS_BAR_CHAR=(█ ▒)
|
||||
|
||||
command() {
|
||||
local -r host=${1?"first parameter must be an host"}
|
||||
local -r iteration=${2?"second parameter must be an iteration number"}
|
||||
local -r cmd=(ping -c "${iteration}" "${host}")
|
||||
|
||||
"${cmd[@]}"
|
||||
}
|
||||
|
||||
draw_progressbar() {
|
||||
local -r progress=${1?"progress is mandatory"}
|
||||
local -r total=${2?"total elements is mandatory"}
|
||||
local -r info_segment=${3:""}
|
||||
local progress_segment
|
||||
local todo_segment
|
||||
|
||||
local -r bar_size=$((COLUMNS - ${#info_segment}))
|
||||
local -r progress_ratio=$((progress * 100 / total))
|
||||
local -r progress_segment_size=$((bar_size * progress_ratio / 100))
|
||||
local -r todo_segment_size=$((bar_size - progress_segment_size))
|
||||
|
||||
printf -v progress_segment "%${progress_segment_size}s" ""
|
||||
printf -v todo_segment "%${todo_segment_size}s" ""
|
||||
|
||||
printf >&2 "%s%s%s\r" \
|
||||
"${info_segment}" \
|
||||
"${progress_segment// /${PROGRESS_BAR_CHAR[0]}}" \
|
||||
"${todo_segment// /${PROGRESS_BAR_CHAR[1]}}"
|
||||
|
||||
}
|
||||
|
||||
parse_output() {
|
||||
while read -r line; do
|
||||
if [[ "$line" =~ icmp_seq=([[:digit:]]{1,}).*time=(.*) ]]; then
|
||||
draw_progressbar \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER" \
|
||||
"Ping in progress (time: ${BASH_REMATCH[2]}) "
|
||||
elif [[ "$line" =~ ^PING(.*\(.*\)).* ]]; then
|
||||
printf "Launch ping command to %s with %d iterations\n" \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER"
|
||||
elif [[ "$line" =~ .*packets\ transmitted.* ]]; then
|
||||
printf "%s\n" "$line"
|
||||
fi
|
||||
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
COLUMNS=$(tput cols)
|
||||
command "aquilenet.fr" "$PING_ITER" > >(parse_output)
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
69
content/articles/2024/bash_printf/files/script7_sigwinch.sh
Normal file
69
content/articles/2024/bash_printf/files/script7_sigwinch.sh
Normal file
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/env bash
|
||||
# shellcheck disable=2317
|
||||
PING_ITER=64
|
||||
PROGRESS_BAR_CHAR=(█ ▒)
|
||||
|
||||
command() {
|
||||
local -r host=${1?"first parameter must be an host"}
|
||||
local -r iteration=${2?"second parameter must be an iteration number"}
|
||||
local -r cmd=(ping -c "${iteration}" "${host}")
|
||||
|
||||
"${cmd[@]}"
|
||||
}
|
||||
trap change_column_size WINCH
|
||||
|
||||
draw_progressbar() {
|
||||
local -r progress=${1?"progress is mandatory"}
|
||||
local -r total=${2?"total elements is mandatory"}
|
||||
local -r info_segment=${3:""}
|
||||
local progress_segment
|
||||
local todo_segment
|
||||
|
||||
local -r bar_size=$((COLUMNS - ${#info_segment}))
|
||||
local -r progress_ratio=$((progress * 100 / total))
|
||||
local -r progress_segment_size=$((bar_size * progress_ratio / 100))
|
||||
local -r todo_segment_size=$((bar_size - progress_segment_size))
|
||||
|
||||
printf -v progress_segment "%${progress_segment_size}s" ""
|
||||
printf -v todo_segment "%${todo_segment_size}s" ""
|
||||
|
||||
printf >&2 "%s%s%s\r" \
|
||||
"${info_segment}" \
|
||||
"${progress_segment// /${PROGRESS_BAR_CHAR[0]}}" \
|
||||
"${todo_segment// /${PROGRESS_BAR_CHAR[1]}}"
|
||||
|
||||
}
|
||||
|
||||
parse_output() {
|
||||
trap change_column_size WINCH
|
||||
while read -r line; do
|
||||
if [[ "$line" =~ icmp_seq=([[:digit:]]{1,}).*time=(.*) ]]; then
|
||||
|
||||
draw_progressbar \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER" \
|
||||
"Ping in progress (time: ${BASH_REMATCH[2]}) "
|
||||
elif [[ "$line" =~ ^PING(.*\(.*\)).* ]]; then
|
||||
printf "Launch ping command to %s with %d iterations\n" \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER"
|
||||
elif [[ "$line" =~ .*packets\ transmitted.* ]]; then
|
||||
printf >&2 "\033[0K\r"
|
||||
printf "%s\n" "$line"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
change_column_size() {
|
||||
printf >&2 "%${COLUMNS}s" ""
|
||||
printf >&2 "\033[0K\r"
|
||||
COLUMNS=$(tput cols)
|
||||
}
|
||||
|
||||
main() {
|
||||
COLUMNS=$(tput cols)
|
||||
command "aquilenet.fr" "$PING_ITER" > >(parse_output)
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
97
content/articles/2024/bash_printf/files/script8_bonus.sh
Normal file
97
content/articles/2024/bash_printf/files/script8_bonus.sh
Normal file
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/env bash
|
||||
# ...
|
||||
# shellcheck disable=2317,2059
|
||||
PING_ITER=16
|
||||
|
||||
# Progress bar dedicated variables
|
||||
# We can control how progress bar work
|
||||
PROGRESS_BAR_CHAR=(█ ▒)
|
||||
|
||||
# control which information is displayed"
|
||||
PROGRESS_BAR_DISPLAY_INFO=1
|
||||
PROGRESS_BAR_DISPLAY_COMPL=1
|
||||
|
||||
# Display template
|
||||
# We can control how informations is displayed
|
||||
PROGRESS_BAR_INFO_TEMPLATE=' %s [%2d/%2d] '
|
||||
PROGRESS_BAR_COMPL_TEMPLATE=' %2d%% '
|
||||
PROGRESS_BAR_TEMPLATE='\033[1m%s%s\033[0m%s%s\r'
|
||||
|
||||
command() {
|
||||
local -r host=${1?"first parameter must be an host"}
|
||||
local -r iteration=${2?"second parameter must be an iteration number"}
|
||||
local -r cmd=(ping -c "${iteration}" "${host}")
|
||||
|
||||
"${cmd[@]}"
|
||||
}
|
||||
|
||||
draw_progressbar() {
|
||||
# function parameters
|
||||
local -r progress=${1?"progress is mandatory"}
|
||||
local -r total=${2?"total elements is mandatory"}
|
||||
local -r info=${3:-"In progress"}
|
||||
|
||||
# function local variables
|
||||
local progress_segment
|
||||
local todo_segment
|
||||
local info_segment=""
|
||||
local compl_segment=""
|
||||
|
||||
if [[ ${PROGRESS_BAR_DISPLAY_INFO:-1} -eq 1 ]]; then
|
||||
printf -v info_segment "${PROGRESS_BAR_INFO_TEMPLATE}" \
|
||||
"$info" "$progress" "$total"
|
||||
fi
|
||||
|
||||
local -r progress_ratio=$((progress * 100 / total))
|
||||
if [[ ${PROGRESS_BAR_DISPLAY_COMPL:-0} -eq 1 ]]; then
|
||||
printf -v compl_segment "${PROGRESS_BAR_COMPL_TEMPLATE}" \
|
||||
"$progress_ratio"
|
||||
fi
|
||||
|
||||
# progress bar construction
|
||||
# calculate each element sizes, bar must fit in ou screen
|
||||
local -r bar_size=$((COLUMNS - ${#info_segment} - ${#compl_segment}))
|
||||
local -r progress_segment_size=$((bar_size * progress_ratio / 100))
|
||||
local -r todo_segment_size=$((bar_size - progress_segment_size))
|
||||
printf -v progress_segment "%${progress_segment_size}s" ""
|
||||
printf -v todo_segment "%${todo_segment_size}s" ""
|
||||
|
||||
printf >&2 "$PROGRESS_BAR_TEMPLATE" \
|
||||
"$info_segment" \
|
||||
"${progress_segment// /${PROGRESS_BAR_CHAR[0]}}" \
|
||||
"${todo_segment// /${PROGRESS_BAR_CHAR[1]}}" \
|
||||
"$compl_segment"
|
||||
}
|
||||
|
||||
parse_output() {
|
||||
trap change_column_size WINCH
|
||||
while read -r line; do
|
||||
if [[ "$line" =~ icmp_seq=([[:digit:]]{1,}).*time=(.*) ]]; then
|
||||
draw_progressbar \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER" \
|
||||
"Ping in progess"
|
||||
elif [[ "$line" =~ ^PING(.*\(.*\)).* ]]; then
|
||||
printf "Launch ping command to %s with %d iterations\n" \
|
||||
"${BASH_REMATCH[1]}" \
|
||||
"$PING_ITER"
|
||||
elif [[ "$line" =~ .*packets\ transmitted.* ]]; then
|
||||
printf >&2 "\033[0K\r"
|
||||
printf "%s\n" "$line"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
change_column_size() {
|
||||
printf >&2 "%${COLUMNS}s" ""
|
||||
printf >&2 "\033[0K\r"
|
||||
COLUMNS=$(tput cols)
|
||||
}
|
||||
|
||||
main() {
|
||||
COLUMNS=$(tput cols)
|
||||
command "aquilenet.fr" "$PING_ITER" > >(parse_output)
|
||||
}
|
||||
|
||||
main
|
||||
exit 0
|
Loading…
Add table
Add a link
Reference in a new issue