সময় বিহ্বল গণনা করতে স্ক্রিপ্টে বাশ করুন


118

আমি আমার আদেশগুলি কার্যকর করার জন্য সময় কাটানোর জন্য গণনায় একটি স্ক্রিপ্ট লিখছি, বিবেচনা করুন:

STARTTIME=$(date +%s)
#command block that takes time to complete...
#........
ENDTIME=$(date +%s)
echo "It takes $($ENDTIME - $STARTTIME) seconds to complete this task..."

আমার ধারণা আমার যুক্তি ঠিক আছে তবে আমি নিম্নলিখিত প্রিন্ট আউটটি দিয়ে শেষ করছি:

"এই কাজটি শেষ হতে কয়েক সেকেন্ড সময় লাগে ..."

আমার স্ট্রিং মূল্যায়নে কিছু ভুল?

আমি বিশ্বাস করি যে ব্যাশ ভেরিয়েবলগুলি টাইপযুক্ত নয়, তবুও বাশে "স্ট্রিং টু ইন্টিজার" পদ্ধতি থাকলে আমি পছন্দ করব।

উত্তর:


83

হয় $(())বা $[]পাটিগণিত অপারেশনের ফলাফল গণনা করার জন্য কাজ করবে। আপনি ব্যবহার করছেন $()যা কেবল স্ট্রিং গ্রহণ করছে এবং এটিকে একটি কমান্ড হিসাবে মূল্যায়ন করছে। এটি কিছুটা সূক্ষ্ম পার্থক্য। আশাকরি এটা সাহায্য করবে.

এই উত্তরের মন্তব্যে যেমন টিঙ্ক ইশারা করেছেন, তেমনি হ্রাস $[]করা হয়েছে, এবং $(())এটি অনুগ্রহ করা উচিত।


7
আপনি two দু'টির চারপাশে অদলবদল করতে চাইতে পারেন, যেমন ব্যাশ ৪.x ম্যান-পৃষ্ঠাতে উল্লেখ করা হয়েছে যে $ []] অবনমিত এবং ভবিষ্যতের সংস্করণগুলিতে সরানো হবে।
Tink

2
ধন্যবাদ, আমি অজানা ছিলাম।
সর্বশক্তিমান এন্টিটি

157

অভ্যন্তরীণ ভেরিয়েবল "$ সেকেন্ডস" ব্যবহার করা আমার কাছে খুব পরিষ্কার মনে হয়েছে

SECONDS=0 ; sleep 10 ; echo $SECONDS


10
কেবল সাফল্য =)
লন কৌত

1
সাফল্যের দরকার, আপনার ব্যবহার করুন
গ্রোমিশ

3
$SECONDSসত্যিই / বিন / ব্যাশের জন্য কাজ করে। এটি / বিন / ড্যাশ, ডেবিয়ান এবং উবুন্টুতে ডিফল্ট শেলটির জন্য কাজ করে না।
ক্যামেরন ট্যাগগার্ট

2
এই সমাধানটির বিপরীতে হ'ল এটি কেবল পুরো সেকেন্ড পরিমাপ করে, অর্থাত্ আপনার যদি উপ-দ্বিতীয় নির্ভুলতার প্রয়োজন হয় তবে ব্যবহারযোগ্য।
সিজন টেকনোলজি

@ প্রযুক্তি প্রযুক্তি হ্যাঁ, আপনি sleep 0.5যদি উপরে ব্যবহার করেন তবে ফলাফলটি কখনও কখনও 0 হয়, কখনও কখনও 1 হয় (কমপক্ষে বাশ 5.0.3 দ্বারা)।
জার্নো

52

আপনি ENDTIMEকমান্ড হিসাবে নম্বরটি কার্যকর করার চেষ্টা করছেন । আপনার মতো একটি ত্রুটিও দেখতে পাওয়া উচিত 1370306857: command not found। পরিবর্তে পাটিগণিত সম্প্রসারণ ব্যবহার করুন :

echo "It takes $(($ENDTIME - $STARTTIME)) seconds to complete this task..."

আপনি পৃথক স্ক্রিপ্টে কমান্ডগুলি সংরক্ষণ করতে পারেন commands.sh, এবং সময় আদেশ ব্যবহার করতে পারেন:

time commands.sh

28

আপনি timeএখানে উপযুক্ত বিন্যাসের স্ট্রিং সহ বাশের কীওয়ার্ডটি ব্যবহার করতে পারেন

TIMEFORMAT='It takes %R seconds to complete this task...'
time {
    #command block that takes time to complete...
    #........
 }

রেফারেন্স সম্পর্কেTIMEFORMAT যা বলে তা এখানে :

এই প্যারামিটারটির মান একটি ফর্ম্যাট স্ট্রিং হিসাবে ব্যবহৃত হয় তা নির্দিষ্ট করে যে কীভাবে time সংরক্ষিত শব্দের সাথে উপস্থাপিত পাইপলাইনের সময়সীমার তথ্য প্রদর্শিত হবে। ' %' অক্ষরটি একটি পালানোর ক্রমটি উপস্থাপন করে যা সময় মূল্য বা অন্যান্য তথ্যে প্রসারিত হয়। অব্যাহতি ক্রম এবং তাদের অর্থ নীচে রয়েছে; বন্ধনীগুলি alচ্ছিক অংশকে বোঝায় den

%%

    A literal ‘%’.
%[p][l]R

    The elapsed time in seconds.
%[p][l]U

    The number of CPU seconds spent in user mode.
%[p][l]S

    The number of CPU seconds spent in system mode.
%P

    The CPU percentage, computed as (%U + %S) / %R. 

Alচ্ছিক পি হ'ল একটি অঙ্ক যা স্পষ্টতা নির্দিষ্ট করে, দশমিক বিন্দুর পরে ভগ্নাংশের সংখ্যার সংখ্যা। 0 এর মানের ফলে দশমিক বিন্দু বা ভগ্নাংশ আউটপুট হয় না। দশমিক পয়েন্টের পরে সর্বাধিক তিনটি স্থানে নির্দিষ্ট করা যেতে পারে; 3 এর চেয়ে বড় পি এর মান 3 এ পরিবর্তিত হয়। p যদি নির্দিষ্ট না করা হয় তবে মান 3 ব্যবহার করা হয়।

ঐচ্ছিক lনির্দিষ্ট করে একটি লম্বা বিন্যাস, মিনিট সহ ফর্মের, MMmSS.FFs। P এর মান ভগ্নাংশ অন্তর্ভুক্ত কিনা তা নির্ধারণ করে।

যদি এই ভেরিয়েবলটি সেট না করা হয় তবে বাশ এমনভাবে কাজ করে যা এর মান রয়েছে

$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'

মানটি যদি নাল হয় তবে কোনও সময় সংক্রান্ত তথ্য প্রদর্শিত হয় না। ফর্ম্যাট স্ট্রিং প্রদর্শিত হয় যখন একটি অনুসরণযোগ্য নিউলাইন যোগ করা হয়।


10

বৃহত সংখ্যার জন্য আমরা আরও পঠনযোগ্য ফর্ম্যাটে মুদ্রণ করতে চাই। নীচের উদাহরণটি অন্যান্য হিসাবে একই রকম হয় তবে "মানব" বিন্যাসেও মুদ্রণ করে:

secs_to_human() {
    if [[ -z ${1} || ${1} -lt 60 ]] ;then
        min=0 ; secs="${1}"
    else
        time_mins=$(echo "scale=2; ${1}/60" | bc)
        min=$(echo ${time_mins} | cut -d'.' -f1)
        secs="0.$(echo ${time_mins} | cut -d'.' -f2)"
        secs=$(echo ${secs}*60|bc|awk '{print int($1+0.5)}')
    fi
    echo "Time Elapsed : ${min} minutes and ${secs} seconds."
}

সাধারণ পরীক্ষা:

secs_to_human "300"
secs_to_human "305"
secs_to_human "59"
secs_to_human "60"
secs_to_human "660"
secs_to_human "3000"

আউটপুট:

Time Elapsed : 5 minutes and 0 seconds.
Time Elapsed : 5 minutes and 5 seconds.
Time Elapsed : 0 minutes and 59 seconds.
Time Elapsed : 1 minutes and 0 seconds.
Time Elapsed : 11 minutes and 0 seconds.
Time Elapsed : 50 minutes and 0 seconds.

অন্যান্য পোস্টে বর্ণিত স্ক্রিপ্টে ব্যবহার করতে (ক্যাপচার স্টার্ট পয়েন্টটি তারপর ফাংশনটি শেষের সাথে কল করুন:

start=$(date +%s)
# << performs some task here >>
secs_to_human "$(($(date +%s) - ${start}))"


5

এটি মাইক কিউয়ের কার্যকারিতার এক-লাইনারের বিকল্প:

secs_to_human() {
    echo "$(( ${1} / 3600 ))h $(( (${1} / 60) % 60 ))m $(( ${1} % 60 ))s"
}

নিস! আমি আমার ব্যাশ কোড সহ সাধারণত খুব ভার্বোজ থাকি, এটি দুর্দান্ত।
মাইক কিউ

এই সঙ্গে মিশ্রন SECONDSলন Kaut থেকে উত্তর এবং যে মন পালন $ / $ {} গাণিতিক ভেরিয়েবল উপর অপ্রয়োজনীয় : তাই সংক্ষিপ্ত তোলে কোড এটা এমনকি ইনলাইন ব্যবহার করা যেতে পারেecho "$((SECONDS/3600))h $(((SECONDS/60)%60))m $((SECONDS%60))s"
এসএসসি

2

অতিবাহিত সেকেন্ড বিকল্পের সাথে সময়টি ব্যবহার করার চেষ্টা করুন:

/usr/bin/time -f%e sleep 1 বাশ অধীনে।

বা \time -f%e sleep 1ইন্টারেক্টিভ ব্যাশে।

টাইম ম্যান পৃষ্ঠা দেখুন:

বাহ্যিক সময় কমান্ড চালানোর জন্য ব্যাশ শেলের ব্যবহারকারীদের একটি স্পষ্ট পথ ব্যবহার করা দরকার, শেল বিল্টিন বৈকল্পিকটি নয়। সিস্টেমে / usr / বিনে সময় ইনস্টল করা হয়, প্রথম উদাহরণটি / usr / bin / সময় wc / etc / হোস্টে পরিণত হবে

এবং

FORMATTING THE OUTPUT
...
    %      A literal '%'.
    e      Elapsed  real  (wall  clock) time used by the process, in
                 seconds.

1
/bin/timeএখানে কাজ করছে না: ওপি একটি ব্লকের উল্লেখ করেছে । সুতরাং আমাদের timeএখানে সত্যিকারের কীওয়ার্ডটি দরকার ।
gniourf_gniourf

-3
start=$(date +%Y%m%d%H%M%S);
for x in {1..5};
do echo $x;
sleep 1; done;
end=$(date +%Y%m%d%H%M%S);
elapsed=$(($end-$start));
ftime=$(for((i=1;i<=$((${#end}-${#elapsed}));i++));
        do echo -n "-";
        done;
        echo ${elapsed});
echo -e "Start  : ${start}\nStop   : ${end}\nElapsed: ${ftime}"

Start  : 20171108005304
Stop   : 20171108005310
Elapsed: -------------6

-3
    #!/bin/bash

    time_elapsed(){
    appstop=$1; appstart=$2

    ss_strt=${appstart:12:2} ;ss_stop=${appstop:12:2}
    mm_strt=${appstart:10:2} ;mm_stop=${appstop:10:2}
     hh_strt=${appstart:8:2} ; hh_stop=${appstop:8:2}
     dd_strt=${appstart:6:2} ; dd_stop=${appstop:6:2}
     mh_strt=${appstart:4:2} ; mh_stop=${appstop:4:2}
     yy_strt=${appstart:0:4} ; yy_stop=${appstop:0:4}

    if [ "${ss_stop}" -lt "${ss_strt}" ]; then ss_stop=$((ss_stop+60)); mm_stop=$((mm_stop-1)); fi
    if [ "${mm_stop}" -lt "0" ]; then mm_stop=$((mm_stop+60)); hh_stop=$((hh_stop-1)); fi
    if [ "${mm_stop}" -lt "${mm_strt}" ]; then mm_stop=$((mm_stop+60)); hh_stop=$((hh_stop-1)); fi
    if [ "${hh_stop}" -lt "0" ]; then hh_stop=$((hh_stop+24)); dd_stop=$((dd_stop-1)); fi
    if [ "${hh_stop}" -lt "${hh_strt}" ]; then hh_stop=$((hh_stop+24)); dd_stop=$((dd_stop-1)); fi

    if [ "${dd_stop}" -lt "0" ]; then dd_stop=$((dd_stop+$(mh_days $mh_stop $yy_stop))); mh_stop=$((mh_stop-1)); fi
    if [ "${dd_stop}" -lt "${dd_strt}" ]; then dd_stop=$((dd_stop+$(mh_days $mh_stop $yy_stop))); mh_stop=$((mh_stop-1)); fi

    if [ "${mh_stop}" -lt "0" ]; then mh_stop=$((mh_stop+12)); yy_stop=$((yy_stop-1)); fi
    if [ "${mh_stop}" -lt "${mh_strt}" ]; then mh_stop=$((mh_stop+12)); yy_stop=$((yy_stop-1)); fi

    ss_espd=$((10#${ss_stop}-10#${ss_strt})); if [ "${#ss_espd}" -le "1" ]; then ss_espd=$(for((i=1;i<=$((${#ss_stop}-${#ss_espd}));i++)); do echo -n "0"; done; echo ${ss_espd}); fi
    mm_espd=$((10#${mm_stop}-10#${mm_strt})); if [ "${#mm_espd}" -le "1" ]; then mm_espd=$(for((i=1;i<=$((${#mm_stop}-${#mm_espd}));i++)); do echo -n "0"; done; echo ${mm_espd}); fi
    hh_espd=$((10#${hh_stop}-10#${hh_strt})); if [ "${#hh_espd}" -le "1" ]; then hh_espd=$(for((i=1;i<=$((${#hh_stop}-${#hh_espd}));i++)); do echo -n "0"; done; echo ${hh_espd}); fi
    dd_espd=$((10#${dd_stop}-10#${dd_strt})); if [ "${#dd_espd}" -le "1" ]; then dd_espd=$(for((i=1;i<=$((${#dd_stop}-${#dd_espd}));i++)); do echo -n "0"; done; echo ${dd_espd}); fi
    mh_espd=$((10#${mh_stop}-10#${mh_strt})); if [ "${#mh_espd}" -le "1" ]; then mh_espd=$(for((i=1;i<=$((${#mh_stop}-${#mh_espd}));i++)); do echo -n "0"; done; echo ${mh_espd}); fi
    yy_espd=$((10#${yy_stop}-10#${yy_strt})); if [ "${#yy_espd}" -le "1" ]; then yy_espd=$(for((i=1;i<=$((${#yy_stop}-${#yy_espd}));i++)); do echo -n "0"; done; echo ${yy_espd}); fi

    echo -e "${yy_espd}-${mh_espd}-${dd_espd} ${hh_espd}:${mm_espd}:${ss_espd}"
    #return $(echo -e "${yy_espd}-${mh_espd}-${dd_espd} ${hh_espd}:${mm_espd}:${ss_espd}")
    }

    mh_days(){
    mh_stop=$1; yy_stop=$2; #also checks if it's leap year or not

    case $mh_stop in
     [1,3,5,7,8,10,12]) mh_stop=31
     ;;
     2) (( !(yy_stop % 4) && (yy_stop % 100 || !(yy_stop % 400) ) )) && mh_stop=29 || mh_stop=28
     ;;
     [4,6,9,11]) mh_stop=30
     ;;
    esac

    return ${mh_stop}
    }

    appstart=$(date +%Y%m%d%H%M%S); read -p "Wait some time, then press nay-key..." key; appstop=$(date +%Y%m%d%H%M%S); elapsed=$(time_elapsed $appstop $appstart); echo -e "Start...: ${appstart:0:4}-${appstart:4:2}-${appstart:6:2} ${appstart:8:2}:${appstart:10:2}:${appstart:12:2}\nStop....: ${appstop:0:4}-${appstop:4:2}-${appstop:6:2} ${appstop:8:2}:${appstop:10:2}:${appstop:12:2}\n$(printf '%0.1s' "="{1..30})\nElapsed.: ${elapsed}"

    exit 0


-------------------------------------------- return
Wait some time, then press nay-key...
Start...: 2017-11-09 03:22:17
Stop....: 2017-11-09 03:22:18
==============================
Elapsed.: 0000-00-00 00:00:01
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.