#!/bin/bash # https://github.com/pollev/bash_progress_bar - See license at end of file # Constants CODE_SAVE_CURSOR="\033[s" CODE_RESTORE_CURSOR="\033[u" CODE_CURSOR_IN_SCROLL_AREA="\033[1A" COLOR_FG="\e[30m" COLOR_BG="\e[42m" COLOR_BG_BLOCKED="\e[43m" RESTORE_FG="\e[39m" RESTORE_BG="\e[49m" # Variables PROGRESS_BLOCKED="false" TRAPPING_ENABLED="false" TRAP_SET="false" CURRENT_NR_LINES=0 setup_scroll_area() { # If trapping is enabled, we will want to activate it whenever we setup the scroll area and remove it when we break the scroll area if [ "$TRAPPING_ENABLED" = "true" ]; then trap_on_interrupt fi lines=$(tput lines) CURRENT_NR_LINES=$lines let lines=$lines-1 # Scroll down a bit to avoid visual glitch when the screen area shrinks by one row log -en "\n" # Save cursor log -en "$CODE_SAVE_CURSOR" # Set scroll region (this will place the cursor in the top left) log -en "\033[0;${lines}r" # Restore cursor but ensure its inside the scrolling area log -en "$CODE_RESTORE_CURSOR" log -en "$CODE_CURSOR_IN_SCROLL_AREA" # Start empty progress bar draw_progress_bar 0 } destroy_scroll_area() { lines=$(tput lines) # Save cursor log -en "$CODE_SAVE_CURSOR" # Set scroll region (this will place the cursor in the top left) log -en "\033[0;${lines}r" # Restore cursor but ensure its inside the scrolling area log -en "$CODE_RESTORE_CURSOR" log -en "$CODE_CURSOR_IN_SCROLL_AREA" # We are done so clear the scroll bar clear_progress_bar # Scroll down a bit to avoid visual glitch when the screen area grows by one row log -en "\n\n" # Once the scroll area is cleared, we want to remove any trap previously set. Otherwise, ctrl+c will exit our shell if [ "$TRAP_SET" = "true" ]; then trap - INT fi } draw_progress_bar() { percentage=$1 lines=$(tput lines) let lines=$lines # Check if the window has been resized. If so, reset the scroll area if [ "$lines" -ne "$CURRENT_NR_LINES" ]; then setup_scroll_area fi # Save cursor log -en "$CODE_SAVE_CURSOR" # Move cursor position to last row log -en "\033[${lines};0f" # Clear progress bar tput el # Draw progress bar PROGRESS_BLOCKED="false" print_bar_text $percentage # Restore cursor position log -en "$CODE_RESTORE_CURSOR" } block_progress_bar() { percentage=$1 lines=$(tput lines) let lines=$lines # Save cursor log -en "$CODE_SAVE_CURSOR" # Move cursor position to last row log -en "\033[${lines};0f" # Clear progress bar tput el # Draw progress bar PROGRESS_BLOCKED="true" print_bar_text $percentage # Restore cursor position log -en "$CODE_RESTORE_CURSOR" } clear_progress_bar() { lines=$(tput lines) let lines=$lines # Save cursor log -en "$CODE_SAVE_CURSOR" # Move cursor position to last row log -en "\033[${lines};0f" # clear progress bar tput el # Restore cursor position log -en "$CODE_RESTORE_CURSOR" } print_bar_text() { local percentage=$1 local cols=$(tput cols) let bar_size=$cols-17 local color="${COLOR_FG}${COLOR_BG}" if [ "$PROGRESS_BLOCKED" = "true" ]; then color="${COLOR_FG}${COLOR_BG_BLOCKED}" fi # Prepare progress bar let complete_size=($bar_size*$percentage)/100 let remainder_size=$bar_size-$complete_size progress_bar=$(log -ne "["; log -en "${color}"; printf_new "#" $complete_size; log -en "${RESTORE_FG}${RESTORE_BG}"; printf_new "." $remainder_size; log -ne "]"); # Print progress bar log -ne " Progress ${percentage}% ${progress_bar}" } enable_trapping() { TRAPPING_ENABLED="true" } trap_on_interrupt() { # If this function is called, we setup an interrupt handler to cleanup the progress bar TRAP_SET="true" trap cleanup_on_interrupt INT } cleanup_on_interrupt() { destroy_scroll_area exit } printf_new() { str=$1 num=$2 v=$(printf "%-${num}s" "$str") log -ne "${v// /$str}" } # SPDX-License-Identifier: MIT # # Copyright (c) 2018--2020 Polle Vanhoof # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE.