สร้างแถบความคืบหน้าในการทุบตี


13

ฉันจะสร้างแถบความคืบหน้าด้วยการทุบตีได้อย่างไร

นี่คือสคริปต์ของฉัน:

 #!/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 แยกกันหรือไม่?
ผู้บัญชาการ Byte

2
ในอาคารผู้โดยสาร
แบล็กฮอว์ก

etaอาจจะทำสิ่งที่คุณต้องการ
aioobe

คำตอบ:


14

whiptail ติดตั้งมาพร้อมกับ Ubuntu และ distros อื่น ๆ มากมายและจะแสดงองค์ประกอบความคืบหน้าแบบเต็มหน้าจอ (แต่ยังคงใช้เทอร์มินัล)

dialogเป็นตัวอย่างของwhiptailดังนั้นตัวอย่างนี้จะทำงานได้ดีกับทั้งสองอย่างเท่าเทียมกัน มันมีองค์ประกอบ UI ขั้นสูงมากขึ้นดังนั้นจึงอาจมีประโยชน์หากคุณกำลังมองหาการโต้ตอบกับผู้ใช้เช่นตัวเลือกไฟล์และแบบฟอร์ม

whiptail

โต้ตอบ

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

โปรดทราบว่าเอาต์พุตสคริปต์ถูกตีความเป็นเปอร์เซ็นต์ดังนั้นคุณอาจต้องปรับเอาท์พุทให้สอดคล้องกัน

Whiptail และ 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คุณสามารถทำให้มันดูสำหรับการส่งออกห่วงหรือสร้างบางเอาท์พุทปลอม e กรัม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ตัวเลือก

  • แมนนวล : คุณต้องไพพ์เปอร์เซ็นต์ความคืบหน้าปัจจุบันไปยังzenityอินพุตมาตรฐานของคำสั่งเพื่ออัพเดตแถบความคืบหน้า
    ตัวอย่างสำหรับสิ่งนี้อาจมีลักษณะเช่นนี้ด้านล่าง โปรดทราบว่าคำสั่งก่อนหน้านี้จะถูกจัดกลุ่มเป็นเชลล์ย่อยเพื่อให้เอาต์พุตทั้งหมดถูกเปลี่ยนเส้นทางไปยังzenityไดอะล็อกไม่ใช่แค่คำสั่งสุดท้าย:

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

ในกรณีนี้ก็จะเป็นตัวเลือก
ผู้บัญชาการ Byte

1
ขออภัยที่รักนี่คือหน้าต่างแถบความคืบหน้าของ GUI ฉันต้องการสร้างแถบความคืบหน้าในเทอร์มินัลเช่นฉันต้องการดูในขณะที่สคริปต์กำลังตรวจสอบ ==>[ ###########--------------] 52%
แบล็กฮอว์ก

1
ใช่ฉันเข้าใจแล้ว. เป็นเพียงที่ฉันได้เขียนครึ่งหนึ่งของคำตอบของฉันเมื่อคุณพูดว่าดังนั้นฉันเพิ่งตัดสินใจที่จะโพสต์ต่อไปในกรณีที่คนอื่นอาจต้องการมันในอนาคต ฉันหวังว่าคุณจะไม่รังเกียจเนื่องจากมีโซลูชั่นที่ใช้เทอร์มินัลค่อนข้างน้อยเช่นกัน
ผู้บัญชาการ Byte

5

รหัสนี้จะทำและไม่ต้องการอะไรเลย (นอกจากทุบตีแน่นอน) มันพิมพ์#สัญญาณตามที่คุณถามในความคิดเห็นของคุณ:

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.