ऐसा ही कुछ भी नहीं देखा गया है और यहाँ सभी कस्टम फ़ंक्शंस अकेले रेंडर करने पर ध्यान केंद्रित करते हैं ... मेरे बहुत ही सरल POSIX कंप्लायंट स्टेप बाय स्टेप एक्सप्लेनेशन्स नीचे दिए गए हैं क्योंकि यह सवाल मामूली नहीं है।
टी एल; डॉ
प्रगति पट्टी को सौंपना बहुत आसान है। यह अनुमान लगाना कि इसका कितना रेंडर होना चाहिए, यह अलग बात है। यह है कि प्रगति पट्टी को कैसे प्रस्तुत करें (चेतन करें) - आप इस उदाहरण को किसी फ़ाइल में कॉपी और पेस्ट कर सकते हैं और इसे चला सकते हैं:
#!/bin/sh
BAR='####################' # this is full bar, e.g. 20 chars
for i in {1..20}; do
echo -ne "\r${BAR:0:$i}" # print $i chars of $BAR from 0 position
sleep .1 # wait 100ms between "frames"
done
{1..20}
- 1 से 20 तक मान
echo -n
- अंत में नई लाइन के बिना प्रिंट करें
echo -e
- छपाई करते समय विशेष वर्णों की व्याख्या करें
"\r"
- गाड़ी वापसी, लाइन की शुरुआत में लौटने के लिए एक विशेष चर
आप इसे किसी भी सामग्री को किसी भी गति से रेंडर कर सकते हैं, इसलिए यह विधि बहुत सार्वभौमिक है, उदाहरण के लिए अक्सर मूर्खतापूर्ण फिल्मों में "हैकिंग" के दृश्य के लिए उपयोग किया जाता है, कोई मजाक नहीं।
पूरा जवाब
समस्या का मांस यह है कि $i
मूल्य का निर्धारण कैसे किया जाता है , अर्थात प्रगति पट्टी का कितना प्रदर्शन करना है। उपर्युक्त उदाहरण में मैंने सिर्फ़ for
सिद्धांत को स्पष्ट करने के लिए लूप में वृद्धि की अनुमति दी है, लेकिन एक वास्तविक जीवन अनुप्रयोग एक अनंत लूप का उपयोग करेगा और $i
प्रत्येक पुनरावृत्ति पर चर की गणना करेगा । कहा गणना करने के लिए इसे निम्नलिखित अवयवों की आवश्यकता है:
- वहां कितना काम होना है
- अब तक कितना काम हुआ है
इसके मामले में cp
स्रोत फ़ाइल के आकार और लक्ष्य फ़ाइल के आकार की आवश्यकता होती है:
#!/bin/sh
$src=/path/to/source/file
$tgt=/path/to/target/file
cp "$src" "$tgt" & # the & forks the `cp` process so the rest
# of the code runs without waiting (async)
BAR='####################'
src_size=$(stat -c%s "$src") # how much there is to do
while true; do
tgt_size=$(stat -c%s "$tgt") # how much has been done so far
i=$(( $tgt_size * 20 / $src_size ))
echo -ne "\r${BAR:0:$i}"
if [ $tgt_size == $src_size ]; then
echo "" # add a new line at the end
break; # break the loop
fi
sleep .1
done
stat
- फ़ाइल आँकड़े जाँचें
-c
- स्वरूपित मान लौटाएं
%s
- कुल आकार
फ़ाइल अनपैकिंग जैसे संचालन के मामले में, स्रोत आकार की गणना करना थोड़ा अधिक कठिन है लेकिन फिर भी असम्पीडित फ़ाइल का आकार प्राप्त करना जितना आसान है:
#!/bin/sh
src_size=$(gzip -l "$src" | tail -n1 | tr -s ' ' | cut -d' ' -f3)
gzip -l
- ज़िप संग्रह के बारे में जानकारी प्रदर्शित करें
tail -n1
- नीचे से 1 लाइन के साथ काम करें
tr -s ' '
- एक के लिए कई रिक्त स्थान का अनुवाद (उन्हें निचोड़ें)
cut -d' ' -f3
- कट 3 स्थान-सीमांकित स्तंभ
यहाँ समस्या का मांस है, हालांकि। यह समाधान कम और सामान्य है। वास्तविक प्रगति की सभी गणना उस डोमेन के लिए कसकर बाध्य है जिसे आप कल्पना करने की कोशिश कर रहे हैं, क्या यह एक एकल फ़ाइल ऑपरेशन, एक टाइमर उलटी गिनती, एक निर्देशिका में फ़ाइलों की बढ़ती संख्या, कई फाइलों पर संचालन, आदि है, इसलिए, यह पुन: उपयोग नहीं किया जा सकता। एकमात्र पुन: प्रयोज्य हिस्सा प्रगति बार प्रतिपादन है। इसका पुन: उपयोग करने के लिए आपको इसे सार करने और एक फ़ाइल (जैसे /usr/lib/progress_bar.sh
) में सहेजने की आवश्यकता है , फिर उन कार्यों को परिभाषित करें जो आपके डोमेन के लिए विशिष्ट इनपुट मानों की गणना करते हैं। यह है कि एक सामान्यीकृत कोड कैसे दिख सकता है (मैंने भी $BAR
गतिशील बनाया क्योंकि लोग इसके लिए पूछ रहे थे, बाकी अब तक स्पष्ट होना चाहिए:)
#!/bin/sh
BAR_length=50
BAR_character='#'
BAR=$(printf "%${BAR_length}s" | tr ' ' $BAR_character)
work_todo=$(get_work_todo) # how much there is to do
while true; do
work_done=$(get_work_done) # how much has been done so far
i=$(( $work_done * $BAR_length / $work_todo ))
echo -ne "\r${BAR:0:$i}"
if [ $work_done == $work_todo ]; then
echo ""
break;
fi
sleep .1
done
printf
- दिए गए प्रारूप में सामान को प्रिंट करने के लिए एक बिलिन
printf '%50s'
- कुछ भी नहीं प्रिंट करें, इसे 50 स्थानों के साथ पैड करें
tr ' ' '#'
- हर स्पेस को हैश साइन में ट्रांसलेट करें
और इस तरह से आप इसका उपयोग करेंगे:
#!/bin/sh
src=/path/to/source/file
tgt=/path/to/target/file
function get_work_todo() {
echo $(stat -c%s "$src")
}
function get_work_done() {
[ -e "$tgt" ] && # if target file exists
echo $(stat -c%s "$tgt") || # echo its size, else
echo 0 # echo zero
}
cp "$src" "$tgt" & # copy in the background
source /usr/lib/progress_bar.sh # execute the progress bar
जाहिर है कि इसे एक फंक्शन में लपेटा जा सकता है, पाइप की धाराओं के साथ काम करने के लिए फिर से लिखा जा सकता है, अन्य भाषा में फिर से लिखा जा सकता है, जो भी आपका जहर है।