일부 프로세스가 완료되기를 기다리는 동안 디스플레이 스피너


13

커맨드 라인이 끝날 때까지 스피너를 표시하려면 어떻게해야합니까? 즉, 스크립트를 실행 중이고이 스크립트가 실행되는 동안 스피너를 표시하고 스크립트가 작업을 완료하면 스피너가 사라집니다.

Bellow는 일반적인 스피너 코드입니다.

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

이전 스피너 코드를 명령에 연결하여 명령이 실행되는 동안 스피너를 표시하고 명령이 작업을 완료하면 스피너가 사라지도록하려면 어떻게해야합니까? 루프 안에 명령을 포함 시키면 스피너와 함께 루프 되므로이 경우 해결책은 무엇입니까?

bash 

답변:


22

당신이 while출구 실제 명령 루프 시계. 각 PID에 대해 / proc 항목이있는 Linux 환경을 가정하지만 다른 방법으로 슬라이스 할 수 있습니다.

#!/bin/bash
# your real command here, instead of sleep
sleep 7 &
PID=$!
i=1
sp="/-\|"
echo -n ' '
while [ -d /proc/$PID ]
do
  printf "\b${sp:i++%${#sp}:1}"
done

9
이것은 CPU 리소스를 소비하는 바쁜 루프입니다. while 루프에서 약간의 지연을 갖는 것이 좋습니다.
ACase

16

이 쉘 스크립트는 당신이 찾고있는 것을해야합니다 :

#!/usr/bin/env bash

show_spinner()
{
  local -r pid="${1}"
  local -r delay='0.75'
  local spinstr='\|/-'
  local temp
  while ps a | awk '{print $1}' | grep -q "${pid}"; do
    temp="${spinstr#?}"
    printf " [%c]  " "${spinstr}"
    spinstr=${temp}${spinstr%"${temp}"}
    sleep "${delay}"
    printf "\b\b\b\b\b\b"
  done
  printf "    \b\b\b\b"
}

("$@") &
show_spinner "$!"

쉘 스크립트를이라는 파일에 저장한다고 가정하면 spinner명령 sleep 10을 실행 하는 동안 다음과 같이이를 호출하여 스피너를 표시 할 수 있습니다 .

$ spinner sleep 10


쉘 스크립트가이라고 가정 spinner하므로 아니오. 스크립트 이름을 가정하면 예제가 옳다고 생각합니다 spinner.
jsears

3

다음과 같이 사용할 수있는 또 다른 멋진 스피너가 있습니다.

spinner ping google.com
echo "ping exited with exit code $?"

spinner sleep 10
echo "sleep exited with exit code $?"

그것은 12 테마를 가지고 무작위로 하나를 선택합니다.

#!/bin/bash
# Shows a spinner while another command is running. Randomly picks one of 12 spinner styles.
# @args command to run (with any parameters) while showing a spinner. 
#       E.g. ‹spinner sleep 10›

function shutdown() {
  tput cnorm # reset cursor
}
trap shutdown EXIT

function cursorBack() {
  echo -en "\033[$1D"
}

function spinner() {
  # make sure we use non-unicode character type locale 
  # (that way it works for any locale as long as the font supports the characters)
  local LC_CTYPE=C

  local pid=$1 # Process Id of the previous running command

  case $(($RANDOM % 12)) in
  0)
    local spin='⠁⠂⠄⡀⢀⠠⠐⠈'
    local charwidth=3
    ;;
  1)
    local spin='-\|/'
    local charwidth=1
    ;;
  2)
    local spin="▁▂▃▄▅▆▇█▇▆▅▄▃▂▁"
    local charwidth=3
    ;;
  3)
    local spin="▉▊▋▌▍▎▏▎▍▌▋▊▉"
    local charwidth=3
    ;;
  4)
    local spin='←↖↑↗→↘↓↙'
    local charwidth=3
    ;;
  5)
    local spin='▖▘▝▗'
    local charwidth=3
    ;;
  6)
    local spin='┤┘┴└├┌┬┐'
    local charwidth=3
    ;;
  7)
    local spin='◢◣◤◥'
    local charwidth=3
    ;;
  8)
    local spin='◰◳◲◱'
    local charwidth=3
    ;;
  9)
    local spin='◴◷◶◵'
    local charwidth=3
    ;;
  10)
    local spin='◐◓◑◒'
    local charwidth=3
    ;;
  11)
    local spin='⣾⣽⣻⢿⡿⣟⣯⣷'
    local charwidth=3
    ;;
  esac

  local i=0
  tput civis # cursor invisible
  while kill -0 $pid 2>/dev/null; do
    local i=$(((i + $charwidth) % ${#spin}))
    printf "%s" "${spin:$i:$charwidth}"

    cursorBack 1
    sleep .1
  done
  tput cnorm
  wait $pid # capture exit code
  return $?
}

("$@") &

spinner $!

2

/ bin / sh와 함께 작동하고 확장 된 bash 매개 변수 대체에 의존하지 않는 최저 공통 분모 스피너를 원하면 다음과 같이 작동합니다.

#!/bin/sh

# The command you are waiting on goes between the ( ) here
# The example below returns a non zero return code

(sleep 20 ; /bin/false) &

pid=$! ; i=0
while ps -a | awk '{print $1}' | grep -q "${pid}"
do
    c=`expr ${i} % 4`
    case ${c} in
       0) echo "/\c" ;;
       1) echo "-\c" ;;
       2) echo "\\ \b\c" ;;
       3) echo "|\c" ;;
    esac
    i=`expr ${i} + 1`
    # change the speed of the spinner by altering the 1 below
    sleep 1
    echo "\b\c"
done

# Collect the return code from the background process

wait ${pid}
ret=$?

# You can report on any errors due to a non zero return code here

exit ${ret}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.