Bazı işlemlerin bitmesini beklerken Spinner'ı görüntüle


13

Spinner'ı komut satırı işini bitirene kadar nasıl gösterebilirim? Başka bir deyişle, bir komut dosyası çalıştırıyorum ve bu komut dosyası çalışırken spinner göstermek istiyorsanız ve komut dosyası bittikten sonra spinner kaybolur.

Körük yaygın bir eğirme kodudur:

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

Komut çalıştığında spinner'ı göstermek için önceki spinner kodunu bir komuta nasıl bağlayabilirim ve komut bittiğinde spinner kaybolur? Komutu döngünün içine dahil edersem, spinner ile döngü yapacaktır, bu durumda çözüm nedir?

bash 

Yanıtlar:


22

whileGerçek komutunuzun çıkması için döngünüzü izleyin. Her PID için / proc girişleri olan bir Linux ortamını varsayacağım, ancak başka şekillerde dilimleyebilirsiniz:

#!/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
Bu, cpu kaynaklarını tüketecek yoğun bir döngüdür. While döngünüzde bir tür gecikme olmasını öneririm.
ACase

16

Bu kabuk betiği aradığınızı yapmalıdır:

#!/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 "$!"

Kabuk komut dosyasını adlı bir dosyada sakladığınızı varsayarsak spinner, komut çalışırken bir döndürücüyü görüntülemek için bunu şöyle çağırabilirsiniz sleep 10:

$ spinner sleep 10


Bu, kabuk betiğinin çağrıldığını varsayar spinner, bu nedenle hayır. Bence örnek doğru, senaryonun adını varsayarsak spinner.
jsears

3

İşte böyle kullanabileceğiniz başka bir fantezi spinner:

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

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

12 teması vardır ve rastgele seçer.

#!/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 ile çalışan ve genişletilmiş bash parametresi değişimine bağlı olmayan en düşük ortak paydalı bir döndürücü istiyorsanız, bu işe yaramalıdır:

#!/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}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.