bash 또는 * NIX의 다른 쉘에서 스크립팅 할 때 몇 초 이상 걸리는 명령을 실행하는 동안 진행 표시 줄이 필요합니다.
예를 들어, 큰 파일을 복사하여 큰 tar 파일을 엽니 다.
쉘 스크립트에 진행률 표시 줄을 추가하는 방법은 무엇입니까?
답변
줄을 덮어 써서 이것을 구현할 수 있습니다. 터미널에 \r
쓰지 않고 줄의 처음으로 돌아갈 때 사용하십시오 \n
.
\n
당신이 라인을 진행 완료되면 작성 하십시오.
사용 echo -ne
:
- 하지 인쇄
\n
및 - 와 같은 이스케이프 시퀀스를 인식
\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'
답변
리눅스 명령 pv를 사용하십시오 :
스트림 중간에 있으면 크기를 알지 못하지만 속도와 총계를 제공하며 거기에서 걸리는 시간을 파악하고 피드백을 얻는 데 필요한 시간을 알 수 있습니다.
답변
선택한 답변보다 더 섹시한 것을 찾고 있었고 내 스크립트도 마찬가지였습니다.
시사
출처
나는 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