Advertisement
pintcat

progress - Draws progress bar & information in a shell console.

Apr 12th, 2021 (edited)
735
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 16.10 KB | None | 0 0
  1. #####################################################################################################################
  2. # progress v3.7.6 - draws progress bar & information in a shell console according to the given value.               #
  3. # Handshake:                                                                                                        #
  4. # $PROGRESS_L1 contains character used to fill the left part of the upper bar (default: "█").                       #
  5. # $PROGRESS_R1 contains character used to fill the right part of the upper bar  (default: "_").                     #
  6. # $PROGRESS_L2 contains character used to fill the left part of the lower bar (default: "▓").                       #
  7. # $PROGRESS_R2 contains character used to fill the right part of the lower bar  (default: "▒").                     #
  8. # $PROGRESS_I contains character(s) drawn at the beginning of the bar (default: unset).                             #
  9. # $PROGRESS_O contains character(s) drawn at the end of the bar (default: unset).                                   #
  10. # $PROGRESS_P contains the percentage value. Make it empty/unset to turn it off (default: 0/on).                    #
  11. # $PROGRESS_FIX contains the fixed width of the progress bar (default: unset).                                      #
  12. # $PROGRESS_ML contains left margin of the bar (default: 0).                                                        #
  13. # $PROGRESS_MR contains right margin of the bar (default: 0).                                                       #
  14. # $PROGRESS_MAX1 contains the maximum of the value to be processed for the upper bar (default: 100).                #
  15. # $PROGRESS_MAX2 contains the maximum of the value to be processed for the lower bar (default: 100).                #
  16. # $PROGRESS_FT sets the frame type; S for single line, D for double line, F for fat frame, T for twin bars, N for   #
  17. #  a narrow framed bar. Anything else will turn off frame design and draw a simple bar instead (default).           #
  18. # $PROGRESS_TSHW sets which time information is displayed: E for elapsed time, R for remaining time, A for all      #
  19. #  these infos (default). Anything else disables the timer display.                                                 #
  20. # $PROGRESS_TPOS sets the position of the timer display: T for top (default), M for middle, B for bottom of the     #
  21. #  progress bar. Anything else disables the timer display.                                                          #
  22. # PROGRESS_TC contains the number of iterations to calculate the average total time. A higher value might be more   #
  23. #  precise, but will also take longer to calculate. (default: 10).                                                  #
  24. # Not using any of these means the corresponding default value is used.                                             #
  25. # Right margin is ignored if $PROGRESS_FIX is set.                                                                  #
  26. # PROGRESS_BAR() must be called with at least a number between 0 & $PROGRESS_MAX1 which is the progress displayed   #
  27. #  by the bar. For twin bars a 2nd value between 0 & $PROGRESS_MAX2 must be given.                                  #
  28. #####################################################################################################################
  29.  
  30. PROGRESS_L1=█
  31. PROGRESS_R1=_
  32. PROGRESS_L2=▓
  33. PROGRESS_R2=░
  34. PROGRESS_I=
  35. PROGRESS_O=
  36. PROGRESS_P=0
  37. PROGRESS_ML=0
  38. PROGRESS_MR=0
  39. PROGRESS_MAX1=100
  40. PROGRESS_MAX2=100
  41. PROGRESS_FT=X
  42. PROGRESS_TOLD=
  43. PROGRESS_TSHW=A
  44. PROGRESS_TPOS=T
  45. PROGRESS_MPOS=M
  46. PROGRESS_TAVR=0
  47. PROGRESS_TREM=---:--:--
  48. PROGRESS_TTOT=0
  49. PROGRESS_TC=10
  50. PROGRESS_FIN=
  51. PROGRESS_STAGE=1
  52.  
  53. # PROGRESS_PREP() - draws top, middle & bottom part of the frame & inserts timer display and/or message text if needed.
  54. # IN:
  55. # $1 contains the token for top (T), middle (M) or bottom (B) part of the frame. It will be compared to $PROGRESS_TPOS
  56. #  and $PROGRESS_MPOS to decide whether the timer display and message is included or not.
  57. # $PROGRESS_ML contains the left margin.
  58. # OUT:
  59. # Draws directly to stdout.
  60.  
  61. PROGRESS_PREP(){
  62.     PROGRESS_FRAME=$(PROGRESS_DRAW 0)
  63.     [ $1 = $PROGRESS_TPOS ] && PROGRESS_FRAME=$PROGRESS_FRAME$(printf "\033["$(($PROGRESS_ML+2))"C$PROGRESS_TOUT")
  64.     [ $1 = $PROGRESS_MPOS ] && PROGRESS_FRAME=$PROGRESS_FRAME$(printf "\033["$(($PROGRESS_ML+2))"C$PROGRESS_MSG")
  65.     printf "$PROGRESS_FRAME"
  66. }      
  67.  
  68. # PROGRESS_DRAW() - does the actual positioning & drawing of the progress bar.
  69. # IN:
  70. # $1 must contain the actual progress given by a number between 0 and $PROGRESS_MAX.
  71. # $PROGRESS_ML contains the left margin.
  72. # $PROGRESS_L1 & $PROGRESS_L2 contain characters used to fill the left part of the corresponding bar.
  73. # $PROGRESS_R1 & $PROGRESS_R2 contain characters used to fill the right part of the corresponding bar.
  74. # $PROGRESS_I contains character(s) drawn at the beginning of the bar.
  75. # $PROGRESS_O contains character(s) drawn at the end of the bar.
  76. # $PROGRESS_MAX1 & $PROGRESS_MAX2 contain the maximum of the value for the corresponding bar to be processed.
  77. # OUT:
  78. # Draws directly to stdout.
  79.  
  80. PROGRESS_DRAW(){
  81.     PROGRESS_COUNT=0
  82.     if [ $PROGRESS_STAGE -eq 1 ]; then
  83.         PROGRESS_L=$PROGRESS_L1
  84.         PROGRESS_R=$PROGRESS_R1
  85.         PROGRESS_MAX=$PROGRESS_MAX1
  86.     else
  87.         PROGRESS_L=$PROGRESS_L2
  88.         PROGRESS_R=$PROGRESS_R2
  89.         PROGRESS_MAX=$PROGRESS_MAX2
  90.     fi
  91.     setterm -linewrap off
  92.     # If left margin was set move the start position to the right according to $PROGRESS_ML.
  93.     if [ $PROGRESS_ML -gt 0 ]; then
  94.         PROGRESS_I_TMP="\033["$PROGRESS_ML"C"$PROGRESS_I
  95.     else
  96.         PROGRESS_I_TMP="$PROGRESS_I"
  97.     fi
  98.     printf "\r$PROGRESS_I_TMP"
  99.     # Draw left part.
  100.     while [ $((PROGRESS_COUNT=$PROGRESS_COUNT+1)) -lt $(($PROGRESS_TOT*$1/$PROGRESS_MAX)) ]; do
  101.         printf %.1s && printf "$PROGRESS_L"
  102.     done
  103.     # Draw the right part.
  104.     while [ $((PROGRESS_COUNT=$PROGRESS_COUNT+1)) -le $PROGRESS_TOT ]; do
  105.         printf %.1s && printf "$PROGRESS_R"
  106.     done
  107.     # Finish drawing, print percentage & clear line.
  108.     printf "$PROGRESS_O%4s" $PROGRESS_P && printf "\033[K\r"
  109.     setterm -linewrap on
  110. }
  111.  
  112. # PROGRESS_CALC() - measures window size; calculates & sets width of the progress bar.
  113. # IN:
  114. # $PROGRESS_FIX contains the fixed width of the progress bar. If not set, the width is calculated according to
  115. #  the window size.
  116. # $PROGRESS_MR contains right margin of the bar.
  117. # $PROGRESS_EXT contains the length extension for the bar; needed to calculate the actual length without $PROGRESS_I
  118. #  and $PROGRESS_O.
  119. # OUT:
  120. # $PROGRESS_TOT contains the total width of the progress bar.
  121. # $PROGRESS_P contains the percentage value displayed at the end of the progress bar.
  122.  
  123. PROGRESS_CALC(){
  124.     PROGRESS_MAX=$PROGRESS_MAX1
  125.     [ $PROGRESS_STAGE -eq 2 ] && PROGRESS_MAX=$PROGRESS_MAX2
  126.     # Fixed width used?
  127.     if [ -n "$PROGRESS_FIX" ]; then
  128.         PROGRESS_MR=0
  129.         PROGRESS_TOT=$PROGRESS_FIX
  130.     else
  131.         # If not, calculate width in relation to window size.
  132.         PROGRESS_TOT=$(($(stty size | awk '{print $2}')-$PROGRESS_ML-$PROGRESS_MR-$PROGRESS_EXT))
  133.         if [ -n "$PROGRESS_P" ]; then
  134.             PROGRESS_TOT=$(($PROGRESS_TOT-4))
  135.             PROGRESS_P=$((100*$1/$PROGRESS_MAX))%
  136.         fi
  137.     fi
  138. }
  139.  
  140. # PROGRESS_TISO() - changes time value into ISO pattern or interger. Given value must be either one of them.
  141. # IN:
  142. # $1 must contain the time value. If it's integer it will be converted into ISO pattern and vice versa. For the ISO
  143. #  pattern use the input format hours:minutes:seconds:milliseconds. The output format, however, will always be
  144. #  hours:minutes:seconds.
  145. # OUT:
  146. # Prints the corresponding value directly to stdout.
  147.  
  148. PROGRESS_TISO(){
  149.     # If input contains anything else but numbers it's considered as ISO pattern & converted into integer.
  150.     if [ -z ${1##*[!0-9+-]*} ]; then
  151.         printf "$1" | awk -F ':' '{print ($1*1000)+$2}'
  152.     else
  153.         PROGRESS_TIN=$1
  154.         [ $PROGRESS_TIN -lt 0 ] && PROGRESS_TIN=0
  155.         PROGRESS_THRS=$(($PROGRESS_TIN/3600000))
  156.         PROGRESS_TMIN=$((($PROGRESS_TIN-$PROGRESS_THRS*3600000)/60000))
  157.         PROGRESS_TSEC=$((($PROGRESS_TIN-($PROGRESS_THRS*3600000)-($PROGRESS_TMIN*60000))/1000))
  158.         printf "%03d" $PROGRESS_THRS
  159.         printf ":%02d" $PROGRESS_TMIN
  160.         printf ":%02d" $PROGRESS_TSEC
  161.     fi
  162. }
  163.  
  164. # PROGRESS_TIME() - counts passing time, calculates remaining time & builds timer display.
  165. # IN:
  166. # $1 must contain the actual progress given by a number between 0 and $PROGRESS_MAX.
  167. # $PROGRESS_TSHW contains the token which sets what the timer display will show. E for elapsed time, R for remaining
  168. #  time, A for both. Anything else will deactivate the timer display.
  169. # PROGRESS_TC contains the number of iterations to calculate the average total time. A higher value might be more
  170. #  precise, but will also take longer to calculate.
  171. # OUT:
  172. # $PROGRESS_TOUT contains the ready-to-use timer display according to the $PROGRESS_TSHW setting.
  173. # $PROGRESS_TPAS contains the elapsed time.
  174. # $PROGRESS_TREM contains the remaining time.
  175. # $PROGRESS_TAVR contains the estimated total time.
  176.  
  177. PROGRESS_TIME(){
  178.     PROGRESS_MAX=$PROGRESS_MAX1
  179.     [ $PROGRESS_STAGE -eq 2 ] && PROGRESS_MAX=$PROGRESS_MAX2
  180.     [ -z $PROGRESS_TC_TMP ] && PROGRESS_TC_TMP=$(($PROGRESS_TC*1000))
  181.     PROGRESS_T=$(date +%s:%3N)
  182.     [ -z $PROGRESS_TOLD ] && PROGRESS_TOLD=$PROGRESS_T
  183.     PROGRESS_TINT=$(($(PROGRESS_TISO $PROGRESS_T)-$(PROGRESS_TISO $PROGRESS_TOLD)))
  184.     PROGRESS_TPAS=$(PROGRESS_TISO $PROGRESS_TINT)
  185.     [ $1 -gt 0 ] && PROGRESS_TTOT=$((($PROGRESS_MAX*1000+$1/2)/$1*$PROGRESS_TINT))
  186.     if [ $((PROGRESS_TC=$PROGRESS_TC-1)) -ge 0 ]; then
  187.         PROGRESS_TAVR=$(($PROGRESS_TAVR+$PROGRESS_TTOT))
  188.     else
  189.         PROGRESS_TREM=$((($PROGRESS_TAVR+$PROGRESS_TC_TMP/2)/$PROGRESS_TC_TMP-$PROGRESS_TINT))
  190.         [ $PROGRESS_TREM -lt 0 ] && PROGRESS_TREM=0
  191.         PROGRESS_TREM=$(PROGRESS_TISO $PROGRESS_TREM)
  192.         PROGRESS_TAVR=0
  193.         PROGRESS_TC=$(($PROGRESS_TC_TMP/1000))
  194.     fi
  195.     case $PROGRESS_TSHW in
  196.         E)
  197.             PROGRESS_TOUT=" Time elapsed: $PROGRESS_TPAS "
  198.             ;;
  199.         R)
  200.             PROGRESS_TOUT=" Time remaining: $PROGRESS_TREM "
  201.             ;;
  202.         A)
  203.             PROGRESS_TOUT=" Time elapsed: $PROGRESS_TPAS, remaining: $PROGRESS_TREM "
  204.             ;;
  205.         *)
  206.             PROGRESS_TPOS=X
  207.             ;;
  208.     esac
  209. }
  210.  
  211. # PROGRESS_BAR() - main part; uses all functions to build a progress bar according to the user settings; contains
  212. #                  presets for 3 different frame types. Call this function for the most complete progress output.
  213. # IN:
  214. # $1 must contain the actual progress given by a number between 0 and $PROGRESS_MAX.
  215. # $PROGRESS_MAX1 & $PROGRESS_MAX2 contain the maximum of the value for the corresponding bar to be processed.
  216. # $PROGRESS_FT contains a token to set the frame type: S for single line, D for double line, F for fat frame, T for
  217. # twin bars, N for a narrow framed bar. Anything else will turn off frame design and draw a simple bar instead.
  218. # $PROGRESS_ML contains the left margin.
  219. # $PROGRESS_MR contains the right margin.
  220. # $PROGRESS_L1 & $PROGRESS_L2 contain characters used to fill the left part of the corresponding bar.
  221. # $PROGRESS_R1 & $PROGRESS_R2 contain characters used to fill the right part of the corresponding bar.
  222. # $PROGRESS_I contains character(s) drawn at the beginning of the bar.
  223. # $PROGRESS_O contains character(s) drawn at the end of the bar.
  224. # $PROGRESS_P contains the percentage value. Make it empty/unset to turn it off.
  225. # $PROGRESS_FIN contains an ANSI code which has to be placed at the end of a line in some cases.
  226. # OUT:
  227. # $PROGRESS_NLIN contains the number of lines from the entry point to the line where the progress bar is drawn.
  228. #  This is just for orientation in case you want to place something next to the progress bar.
  229. #  Simply call PROGRESS_BAR without argument to obtain the value for the corresponding frame type.
  230. # Anything else is drawn directly to stdout.
  231.  
  232. PROGRESS_BAR(){
  233.     case $PROGRESS_FT in
  234.         S)
  235.             PROGRESS_NLIN=2
  236.             ;;
  237.         D)
  238.             PROGRESS_NLIN=2
  239.             ;;
  240.         F)
  241.             PROGRESS_NLIN=3
  242.             ;;
  243.         T)
  244.             PROGRESS_NLIN=2
  245.             ;;
  246.         N)
  247.             PROGRESS_NLIN=2
  248.             ;;
  249.     esac
  250.     # Is input integer & between 0 & $PROGRESS_MAX1?
  251.     [ -z ${1##*[!0-9]*} ] || [ $1 -lt 0 ] || [ $1 -gt $PROGRESS_MAX1 ] && return 1
  252.     PROGRESS_EXT=$((${#PROGRESS_I}+${#PROGRESS_O}))
  253.     PROGRESS_TIME $1
  254.     case $PROGRESS_FT in
  255.         S)
  256.             PROGRESS_EXT=2
  257.             PROGRESS_P_TMP=$PROGRESS_P
  258.             PROGRESS_MR=$(($PROGRESS_MR+4))
  259.             PROGRESS_R_TMP=$PROGRESS_R1
  260.             PROGRESS_R1=─
  261.             PROGRESS_I=┌
  262.             PROGRESS_O=┐
  263.             PROGRESS_P=
  264.             PROGRESS_CALC $1
  265.             PROGRESS_PREP T    # draw top line of the frame
  266.             printf "\n\n"
  267.             PROGRESS_I=└
  268.             PROGRESS_O=┘
  269.             PROGRESS_PREP B    # draw bottom line of the frame
  270.             printf "\033[A"
  271.             PROGRESS_I=│
  272.             PROGRESS_O=│
  273.             PROGRESS_R1=$PROGRESS_R_TMP
  274.             PROGRESS_P=$PROGRESS_P_TMP
  275.             PROGRESS_MR=$(($PROGRESS_MR-4))
  276.             PROGRESS_FIN="\033[A"
  277.             ;;
  278.         D)
  279.             PROGRESS_EXT=2
  280.             PROGRESS_P_TMP=$PROGRESS_P
  281.             PROGRESS_MR=$(($PROGRESS_MR+4))
  282.             PROGRESS_R_TMP=$PROGRESS_R1
  283.             PROGRESS_R1=═
  284.             PROGRESS_I=╔
  285.             PROGRESS_O=╗
  286.             PROGRESS_P=
  287.             PROGRESS_CALC $1
  288.             PROGRESS_PREP T    # draw top line of the frame
  289.             printf "\n\n"
  290.             PROGRESS_I=╚
  291.             PROGRESS_O=╝
  292.             PROGRESS_PREP B    # draw bottom line of the frame
  293.             printf "\033[A"
  294.             PROGRESS_I=║
  295.             PROGRESS_O=║
  296.             PROGRESS_R1=$PROGRESS_R_TMP
  297.             PROGRESS_P=$PROGRESS_P_TMP
  298.             PROGRESS_MR=$(($PROGRESS_MR-4))
  299.             PROGRESS_FIN="\033[A"
  300.             ;;
  301.         F)
  302.             PROGRESS_EXT=2
  303.             PROGRESS_P_TMP=$PROGRESS_P
  304.             PROGRESS_MR=$(($PROGRESS_MR+4))
  305.             PROGRESS_R_TMP=$PROGRESS_R1
  306.             PROGRESS_TPOS=X
  307.             PROGRESS_R1=▄
  308.             PROGRESS_I=▄
  309.             PROGRESS_O=▄
  310.             PROGRESS_P=
  311.             printf "\033["$PROGRESS_ML"C$PROGRESS_TOUT\n"
  312.             PROGRESS_CALC $1
  313.             PROGRESS_PREP T    # draw top line of the frame
  314.             printf "\n\n"
  315.             PROGRESS_R1=▀
  316.             PROGRESS_I=▀
  317.             PROGRESS_O=▀
  318.             PROGRESS_PREP B    # draw bottom line of the frame
  319.             printf "\033[A"
  320.             if [ $1 -eq $PROGRESS_MAX1 ]; then
  321.                 PROGRESS_O=█
  322.             else
  323.                 PROGRESS_O=▐
  324.             fi
  325.             PROGRESS_I=█
  326.             PROGRESS_R1=$PROGRESS_R_TMP
  327.             PROGRESS_P=$PROGRESS_P_TMP
  328.             PROGRESS_MR=$(($PROGRESS_MR-4))
  329.             PROGRESS_FIN="\033[2A"
  330.             ;;
  331.         T)
  332.             [ -z ${2##*[!0-9]*} ] || [ $2 -lt 0 ] || [ $2 -gt $PROGRESS_MAX2 ] && return 1
  333.             PROGRESS_EXT=2
  334.             PROGRESS_P_TMP=$PROGRESS_P
  335.             PROGRESS_MR=$(($PROGRESS_MR+4))
  336.             PROGRESS_R_TMP=$PROGRESS_R1
  337.             PROGRESS_R1=─
  338.             PROGRESS_I=┌
  339.             PROGRESS_O=┐
  340.             PROGRESS_P=
  341.             PROGRESS_CALC $1
  342.             PROGRESS_PREP T    # draw top line of the frame
  343.             printf "\n\n"
  344.             PROGRESS_I=├
  345.             PROGRESS_O=┤
  346.             PROGRESS_PREP M    # draw middle line of the frame
  347.             printf "\n\n"
  348.             PROGRESS_I=└
  349.             PROGRESS_O=┘
  350.             PROGRESS_PREP B    # draw bottom line of the frame
  351.             printf "\033[3A"
  352.             PROGRESS_I=│
  353.             PROGRESS_O=│
  354.             PROGRESS_R1=$PROGRESS_R_TMP
  355.             PROGRESS_P=$PROGRESS_P_TMP
  356.             PROGRESS_MR=$(($PROGRESS_MR-4))
  357.             PROGRESS_FIN="\033[3A"
  358.             ;;
  359.         N)
  360.             PROGRESS_EXT=2
  361.             PROGRESS_R1="\033[7m━\033[0m"
  362.             PROGRESS_L1=█
  363.             PROGRESS_I=▐
  364.             PROGRESS_O=▌
  365.             ;;
  366.     esac
  367.     if [ $PROGRESS_FT != S ] && [ $PROGRESS_FT != D ] && [ $PROGRESS_FT != F ] && [ $PROGRESS_FT != T ]; then
  368.         case $PROGRESS_TPOS in
  369.             T)
  370.                 PROGRESS_TOUT="\033["$(($PROGRESS_ML))"C$PROGRESS_TOUT\n"
  371.                 PROGRESS_FIN="\033[A"
  372.                 ;;
  373.             B)
  374.                 PROGRESS_TOUT="\n\033["$(($PROGRESS_ML))"C$PROGRESS_TOUT\033[A"
  375.                 ;;
  376.         esac
  377.         printf "$PROGRESS_TOUT"
  378.     fi
  379.     PROGRESS_CALC $1
  380.     PROGRESS_DRAW $1
  381.     if [ $PROGRESS_FT = T ] && [ -n "$2" ]; then
  382.         PROGRESS_STAGE=2
  383.         printf "\n\n"
  384.         PROGRESS_CALC $2
  385.         PROGRESS_DRAW $2
  386.         PROGRESS_STAGE=1
  387.     fi
  388.     printf "$PROGRESS_FIN"
  389. }
  390.  
  391. # ANSI escape sequences to move the cursor around the screen at will...
  392.  
  393. # - Position the Cursor:
  394. #   \033[<L>;<C>H   Or  \033[<L>;<C>f
  395. #   puts the cursor at line L and column C.
  396. # - Move the cursor up N lines:
  397. #   \033[<N>A
  398. # - Move the cursor down N lines:
  399. #   \033[<N>B
  400. # - Move the cursor forward N columns:
  401. #   \033[<N>C
  402. # - Move the cursor backward N columns:
  403. #   \033[<N>D
  404.  
  405. # - Clear the screen, move to (0,0):
  406. #   \033[2J
  407. # - Erase to end of line:
  408. #   \033[K
  409.  
  410. # - Save cursor position:
  411. #   \033[s
  412. # - Restore cursor position:
  413. #   \033[u
  414.  
  415. # ASCII characters to draw lines...
  416.  
  417. # ═ ║ ╔ ╗ ╚ ╝ ╬ ╠ ╣ ╦ ╩
  418.  
  419. # ─ │ ┌ ┐ └ ┘ ┼ ├ ┤ ┬ ┴
  420.  
  421. # ╟ ╫ ╢ ╓ ╥ ╖ ╙ ╨ ╜
  422.  
  423. # ╞ ╪ ╡ ╒ ╤ ╕ ╘ ╧ ╛
  424.  
  425. # █ ▓ ▒ ░ ▄ ▀ ━ ▌ ▐ ■
  426.  
  427.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement