bash에서 진행률 표시 줄 만들기


13

bash로 진행률 표시 줄을 어떻게 만들 수 있습니까?

이것은 내 스크립트입니다.

 #!/bin/bash
 pass='number1 number12 number13 number14 number15 number16'
 chk='number14'
 for i in $pass ; do
 if [ "$i" == "$chk" ]; then
 echo ' Found ^_^'
 else
 echo 'loading 50%'
 fi
 done

echo 'loading 50%'진행률 표시 줄을 만들기 위해 다른 것으로 바꾸고 싶습니다 .


1
터미널의 진행률 표시 줄 또는 별도의 GUI 창에 진행률 표시 줄이 있습니까?
바이트 사령관

2
터미널에서
블랙 호크

eta당신이 원하는 것을 할 수 있습니다.
aioobe 2016 년

답변:


14

whiptail Ubuntu 및 기타 여러 배포판에 사전 설치되어 있으며 전체 화면 (아직 터미널 기반) 진행 요소를 표시합니다.

dialog은의 수퍼 세트이므로이 whiptail예제는 둘 다 동일하게 작동합니다. 고급 UI 요소를 제공하므로 파일 선택기 및 양식과 같은 사용자 상호 작용을 찾고 있다면 유용 할 수 있지만 많은 시스템에 사전 설치되어 있지 않다는 단점이 있습니다.

채찍

대화

for i in $(seq 1 100)
do
    sleep 0.1 
    echo $i
done | whiptail --title 'Test script' --gauge 'Running...' 6 60 0

스크립트 출력은 백분율로 해석되므로 그에 따라 출력을 조정해야 할 수도 있습니다.

Whiptail and Dialog를 사용하면 런타임에 다소 복잡한 구문을 통해 텍스트를 수정할 수 있습니다.

phases=( 
    'Locating Jebediah Kerman...'
    'Motivating Kerbals...'
    'Treating Kessler Syndrome...'
    'Recruiting Kerbals...'
)   

for i in $(seq 1 100); do  
    sleep 0.1

    if [ $i -eq 100 ]; then
        echo -e "XXX\n100\nDone!\nXXX"
    elif [ $(($i % 25)) -eq 0 ]; then
        let "phase = $i / 25"
        echo -e "XXX\n$i\n${phases[phase]}\nXXX"
    else
        echo $i
    fi 
done | whiptail --title 'Kerbal Space Program' --gauge "${phases[0]}" 6 60 0

pv파일 또는 스트림을 통해 파이프되는 진행 상황을 보여줍니다. 그러나 루프와 같은 사용자 지정 작업의 진행률을 표시하는 데 (쉽게?) 사용할 수 없습니다. 스트림을 위해 특별히 설계되었습니다.

$ head -c 1G < /dev/urandom | pv -s 1G > /dev/null
 277MB 0:00:16 [17.4MB/s] [========>                           ] 27% ETA 0:00:43

pv유용한 실제 예 :

# progress while importing a DB dump
pv mybigfile.sql | mysql -uroot -p dbname

# importing straight from a remote server
ssh user@server 'cat mybigfile.sql.gz' | pv | gzip -cd | mysql -uroot -p dbname

# taking a snapshot of a btrfs partition
btrfs send /snapshots/$date | pv | btrfs receive /mnt/backup/root

pv또는 스타일로 한 줄 진행률 표시 줄을 제공하는 명령을 wget모르지만 다른 사람들이 공유 한 것처럼 해당 기능을 추가하는 간단한 Bash / Perl / sed 스크립트가 많이 있습니다.


루프의 프로세스를 보여주기 pv위해 루프의 출력을 찾거나 echo매번 반복 할 때마다 가짜 출력을 생성하고 파이프를 연결 pv하고 반복 횟수를 지정하십시오 -s. 원하지 않으면 루프의 stdout을로 리디렉션해야합니다 /dev/null. 다음은이 접근법을 보여주는 예 입니다.
디저트

6

zenity간단한 GTK 대화창을 만드는 데 사용할 수 있습니다 . 사용 가능한 옵션 중 하나는 진행률 표시 줄 대화 상자입니다.

를 사용하여 이러한 창을 만듭니다 zenity --progress. 유용하게 사용하려면 아래 옵션 중 일부를 추가하여 추가 정보를 지정해야합니다 (에서 발췌 man zenity).

   Progress options
   --text=STRING
          Set the dialog text
   --percentage=INT
          Set initial percentage
   --auto-close
          Close dialog when 100% has been reached
   --auto-kill
          Kill parent process if cancel button is pressed
   --pulsate
          Pulsate progress bar
   --no-cancel
          Hides the cancel button

두 가지 모드가 있습니다.

  • 맥동 : 진행률 표시 줄이 맥동하고 있습니다. 단지 무언가가 실행 중임을 나타내지 만 진행 상황에 대해서는 아무 것도 알려주지 않습니다. --pulsating옵션 을 설정하면 됩니다.

  • manual : zenity진행률 표시 줄을 업데이트하려면 현재 진행률을 명령의 표준 입력으로 파이프해야 합니다.
    이에 대한 예는 다음과 같습니다. 이전 명령은 서브 쉘로 그룹화되어 zenity마지막 명령뿐만 아니라 모든 출력이 대화 상자 로 경로 재 지정됩니다 .

    (echo 10; sleep 2; echo 20; sleep 2; echo 50; sleep 2) | zenity --progress

이것이 옵션 일 수도 있습니다.
바이트 사령관

1
나의 친애 죄송합니다,이>, 내가 == 예를 들어 내가 스크립트를 검사하는 동안 그것을보고 싶어, 터미널에서 진행 표시 줄을 만들려면 GUI 진행률 표시 줄 창입니다[ ###########--------------] 52%
블랙 호크

1
네 이해했습니다. 그것은 당신이 그렇게 말할 때 이미 내 대답의 절반을 썼다는 것입니다. 터미널 기반 솔루션이 상당히 많기 때문에 걱정하지 마십시오.
바이트 사령관

5

이 코드는 그것을 할 것이고, bash 이외의 것은 필요하지 않습니다. #귀하의 의견에서 요구 한 것처럼 표지판을 인쇄 합니다.

pass='number1 number12 number13 number14 number15 number16'
chk='number14'
passarr=($pass)
lenProgressBar=${#passarr[@]}

echo -n '['
i=0

while [ $i -lt $lenProgressBar ]; do
    echo -n '-'
    ((i++))
done

echo -n ']'
i=0

while [ $i -lt $lenProgressBar ]; do
    echo -e -n '\b'
    ((i++))
done

echo -e -n '\b'
for i in $pass ; do
    if [ "$i" = "$chk" ]; then
        echo -e '#\nFound ^_^'
        break
    else
        echo -n '#'
    fi
done

그러나 확인해야 할 것이 많으면 화면에 #표시가 나타납니다. 이 문제를 해결하려면 다음 코드를 시도하십시오.

lenProgressBar=5
pass='number1 number12 number13 number14 number15 number16'
chk='number14'
passarr=($pass)
lenPass=${#passarr[@]}

if [ $lenProgressBar -gt $lenPass ]; then
    lenProgressBar=lenPass
elif [ $lenProgressBar -lt 1 ]; then
    lenProgressBar=1
fi

let "chksForEqualsPrint = $lenPass / $lenProgressBar"
echo -n '['
i=0

while [ $i -lt $lenProgressBar ]; do
    echo -n '-'
    ((i++))
done

echo -n ']'
i=0

while [ $i -lt $lenProgressBar ]; do
    echo -e -n '\b'
    ((i++))
done

echo -e -n '\b'
n=1

for i in $pass ; do
    if [ "$i" = "$chk" ]; then
        echo -e '\nFound ^_^'
        break
    else
        if [ $n -eq $chksForEqualsPrint ]; then
            echo -n '#'
            n=1
        else
            ((n++))
        fi
    fi
done

첫 번째 줄의 5 ( lenProgressBar=5)를 진행률 표시 줄 길이로 변경하십시오 . #길이가 긴 진행 표시 줄보다 길이 가 긴 표시를 인쇄하는 데 시간이 오래 걸리지 만 진행 표시 줄의 길이가 화면 크기를 초과하지 않도록하십시오. 당신이하면 잘 작동하지 않습니다. (확인중인 항목 수보다 많거나 1보다 작은 진행률 표시 줄을 사용할 수 없습니다.)


1
당신은 사용할 수있는 tput cols터미널 윈도우의 폭을 감지하고 그에 따라 진행 막대를 확장 할 수 있습니다.
Mikkel

1

ansi 이스케이프 코드를 사용하는 또 다른 방법은 다음과 같습니다.

#!/bin/bash

pass='number1 number2 number 3 number4 number12 number13 number14 number15 number16'
chk='number15'
result="Not Found!"

echo
echo -n "Working... "
echo -ne "\033[1;32m\033[7m\033[?25l"

for i in $pass ; do
   sleep .4s
   if [ "$i" == "$chk" ]; then
      result="  Found ^_^"
      break
   else
      echo -n " "
   fi
done

echo -ne "\r\033[0m\033[K\033[?25h"
echo $result
echo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.