[bash] 쉘 스크립트에 진행률 표시 줄을 추가하는 방법?

bash 또는 * NIX의 다른 쉘에서 스크립팅 할 때 몇 초 이상 걸리는 명령을 실행하는 동안 진행 표시 줄이 필요합니다.

예를 들어, 큰 파일을 복사하여 큰 tar 파일을 엽니 다.

쉘 스크립트에 진행률 표시 줄을 추가하는 방법은 무엇입니까?



답변

줄을 덮어 써서 이것을 구현할 수 있습니다. 터미널에 \r쓰지 않고 줄의 처음으로 돌아갈 때 사용하십시오 \n.

\n당신이 라인을 진행 완료되면 작성 하십시오.

사용 echo -ne:

  1. 하지 인쇄 \n
  2. 와 같은 이스케이프 시퀀스를 인식 \r합니다.

데모는 다음과 같습니다.

echo -ne '#####                     (33%)\r'
sleep 1
echo -ne '#############             (66%)\r'
sleep 1
echo -ne '#######################   (100%)\r'
echo -ne '\n'

아래 주석에서, puk은 긴 줄로 시작하여 짧은 줄을 작성하려는 경우이 “실패”를 언급합니다.이 경우 긴 줄의 길이를 덮어 써야합니다 (예 : 공백).


답변

스피너를 만드는 방법에 관심이있을 수도 있습니다 .

Bash에서 스피너를 사용할 수 있습니까?

확실한!

i=1
sp="/-\|"
echo -n ' '
while true
do
    printf "\b${sp:i++%${#sp}:1}"
done

루프가 반복 될 때마다 sp 문자열에 다음 문자가 표시되고 끝에 도달 할 때 줄 바꿈됩니다. (i는 표시 할 현재 문자의 위치이고 $ {# sp}는 sp 문자열의 길이입니다).

\ b 문자열은 ‘backspace’문자로 대체됩니다. 또는 \ r을 사용하여 줄의 처음으로 돌아갈 수 있습니다.

속도를 늦추려면 루프 내부 (printf 뒤)에 휴면 명령을 입력하십시오.

POSIX는 다음과 같습니다.

sp='/-\|'
printf ' '
while true; do
    printf '\b%.1s' "$sp"
    sp=${sp#?}${sp%???}
done

많은 작업을 수행하는 루프가 이미있는 경우 각 반복 시작시 다음 함수를 호출하여 스피너를 업데이트 할 수 있습니다.

sp="/-\|"
sc=0
spin() {
   printf "\b${sp:sc++:1}"
   ((sc==${#sp})) && sc=0
}
endspin() {
   printf "\r%s\n" "$@"
}

until work_done; do
   spin
   some_work ...
done
endspin

답변

일부 게시물은 명령의 진행 상황을 표시하는 방법을 보여주었습니다. 그것을 계산하기 위해, 당신은 얼마나 진행했는지 볼 필요가 있습니다. BSD 시스템에서 dd (1)와 같은 일부 명령은 SIGINFO신호를 받아들이고 진행 상황을보고합니다. Linux 시스템에서 일부 명령은와 유사하게 응답합니다 SIGUSR1. 이 기능이 사용 가능한 경우 입력을 파이프하여 dd처리 된 바이트 수를 모니터 할 수 있습니다.

또는 lsof파일 읽기 포인터의 오프셋을 확보하여 진행률을 계산하는 데 사용할 수 있습니다 . 지정된 프로세스 또는 파일 처리 진행률을 표시하는 pmonitor 라는 명령을 작성했습니다 . 그것으로 당신은 다음과 같은 일을 할 수 있습니다.

$ pmonitor -c gzip
/home/dds/data/mysql-2015-04-01.sql.gz 58.06%

이전 버전의 Linux 및 FreeBSD 셸 스크립트가 내 블로그에 나타납니다 .


답변

다른 날에 쓴 쉬운 진행률 표시 줄 기능이 있습니다.

#!/bin/bash
# 1. Create ProgressBar function
# 1.1 Input is currentState($1) and totalState($2)
function ProgressBar {
# Process data
    let _progress=(${1}*100/${2}*100)/100
    let _done=(${_progress}*4)/10
    let _left=40-$_done
# Build progressbar string lengths
    _fill=$(printf "%${_done}s")
    _empty=$(printf "%${_left}s")

# 1.2 Build progressbar strings and print the ProgressBar line
# 1.2.1 Output example:                           
# 1.2.1.1 Progress : [########################################] 100%
printf "\rProgress : [${_fill// /#}${_empty// /-}] ${_progress}%%"

}

# Variables
_start=1

# This accounts as the "totalState" variable for the ProgressBar function
_end=100

# Proof of concept
for number in $(seq ${_start} ${_end})
do
    sleep 0.1
    ProgressBar ${number} ${_end}
done
printf '\nFinished!\n'

또는
https://github.com/fearside/ProgressBar/에서


답변

리눅스 명령 pv를 사용하십시오 :

http://linux.die.net/man/1/pv

스트림 중간에 있으면 크기를 알지 못하지만 속도와 총계를 제공하며 거기에서 걸리는 시간을 파악하고 피드백을 얻는 데 필요한 시간을 알 수 있습니다.


답변

선택한 답변보다 더 섹시한 것을 찾고 있었고 내 스크립트도 마찬가지였습니다.

시사

진행중인 progress-bar.sh

출처

나는 github에 넣었다.progress-bar.sh

progress-bar() {
  local duration=${1}


    already_done() { for ((done=0; done<$elapsed; done++)); do printf "▇"; done }
    remaining() { for ((remain=$elapsed; remain<$duration; remain++)); do printf " "; done }
    percentage() { printf "| %s%%" $(( (($elapsed)*100)/($duration)*100/100 )); }
    clean_line() { printf "\r"; }

  for (( elapsed=1; elapsed<=$duration; elapsed++ )); do
      already_done; remaining; percentage
      sleep 1
      clean_line
  done
  clean_line
}

용법

 progress-bar 100


답변

GNU tar 에는 간단한 진행 표시 줄의 기능을 제공하는 유용한 옵션이 있습니다.

(…) 사용 가능한 다른 검사 점 작업은 ‘dot'(또는 ‘.’)입니다. tar는 표준 목록 스트림에 단일 점을 인쇄하도록 지시합니다. 예 :

$ tar -c --checkpoint=1000 --checkpoint-action=dot /var
...

다음과 같은 방법으로 동일한 효과를 얻을 수 있습니다.

$ tar -c --checkpoint=.1000 /var