아래와 같이 BASH에서 매우 기본적인 진행률 표시줄을 만들었습니다.
doned=$1 #amount completed
total=$2 #total amount
doned=`echo $doned $total | awk '{print ($1/$2)}'`
total=`tput cols | awk '{print $1-10}'`
doned=`echo $doned $total | awk '{print int(($1*$2))}'`
echo -n $doned"% [ "
for i in $(seq 1 $doned); do
echo -n "="
done
for i in $(seq $((doned+1)) $total); do
echo -n "-"
done
echo " ]"
이것은 내가 원하는 방식으로 정확하게 작동합니다.
이 스크립트는 다른 스크립트의 루프 내에서 실행됩니다. 터미널 하단이나 기타 고정된 위치에 항상 표시되기를 원합니다.
루프는 다음과 같습니다.
for i in 10 20 30 40; do
echo -n "Do you want to continue on to the next step? (y/n): ";
read $yn
if [[ "$yn" == "n" ]] || [[ "$yn" == "N" ]]; then
exit 1; # stop the script
d_3=0;
fi
doned=`some command` ### Get number of completed files
totalss=`some other command` ### Get total number of files
bash ./libraries/prog.sh $doned $totalss
done
그래서 제가 원하는 것은 값을 입력하거나 무언가가 표시되는 경우에도 진행률 표시줄이 하단에 유지되는 것입니다. 추가로 설치하지 않고 이 작업을 수행할 수 있는 방법이 있습니까? 이 스크립트를 사용하려는 대부분의 컴퓨터는 Debian 버전 8+ 또는 Ubuntu 16+ 시스템입니다.
답변1
@MatrixManAtYrService가 제안한 작업을 수행하기 위해 테스트 스크립트를 작성했습니다. 나는 이 솔루션이 U&L SE가 적용되는 모든 시스템에서 작동하지 않는다는 것을 알고 있지만 이것이 내가 요구하는 사양을 충족합니다.
#!/bin/bash
# go to last line and print the empty progress bar
tput sc #save the current cursor position
tput cup $((`tput lines`-1)) 3 # go to last line
echo -n "[" # the next 5 lines just print the required stuff to make the bar
for i in $(seq 1 $((`tput cols`-10))); do
echo -n "-"
done
echo -n "]"
tput rc # bring the cursor back to the last saved position
# the actual loop which does the script's main job
for i in $(seq 0 10 100); do
# print the filled progress bar
tput sc #save the current cursor position
doned=${i} #example value for completed amount
total=100 #example value for total amount
doned=`echo $doned $total | awk '{print ($1/$2)}'` # the next three lines calculate how many characters to print for the completed amount
total=`tput cols | awk '{print $1-10}'`
doned=`echo $doned $total | awk '{print int(($1*$2))}'`
tput cup $((`tput lines`-1)) 4 #go to the last line
for l in $(seq 1 $doned); do #this loop prints the required no. of "="s to fill the bar
echo -n "="
done
tput rc #bring the cursor back to the last saved position
# the next 7 lines are to find the row on which the cursor is currently on to check if it
# is at the last line
# (based on the accepted answer of this question: https://stackoverflow.com/questions/2575037/)
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
tput u7 > /dev/tty
IFS=';' read -r -d R -a pos
stty $oldstty
row=$((${pos[0]:2} - 1))
# check if the cursor is on the line before the last line, if yes, clear the terminal,
# and make the empty bar again and fill it with the required amount of "="s
if [ $row -gt $((`tput lines`-2)) ]; then
clear
tput sc
tput cup $((`tput lines`-1)) 3
echo -n "["
for j in $(seq 1 $((`tput cols`-10))); do
echo -n "-"
done
echo -n "]"
tput cup $((`tput lines`-1)) 4
for k in $(seq 1 $doned); do
echo -n "="
done
tput rc
fi
# this is just to show that the cursor is behaving correctly
read -p "Do you want to continue? (y/n)" yn;
done
# the next few lines remove the progress bar after the program is over
tput sc # save the current cursor position
tput cup $((`tput lines`-1)) 3 # go to the line with the progress bar
tput el # clear the current line
tput rc # go back to the saved cursor position
터미널을 지우는 것보다 마지막 줄의 오버플로를 처리하는 더 좋은 방법이 있어야 합니다. 이는 @MatrixManAtYrService가 제안한 개념 증명에 가깝습니다. 제한 사항에 대한 개선 사항이나 의견을 환영합니다.
답변2
답변3
쉘 스크립트에서 진행률 표시줄을 얻는 쉬운 방법은 주석에서 언급한 대로hiptail 또는 대화 상자를 사용하는 것입니다. 대부분의 Linux 배포판에서는 둘 중 하나 또는 둘 다를 사용할 수 있습니다.
OP는 의견에서 적성 설치 프로그램을 언급했습니다. Aptitude는 대화 상자와 마찬가지로 ncurses 라이브러리를 사용하는 바이너리입니다.