কীভাবে কার্যকরভাবে কোনও স্ক্রিপ্টের কার্যকর করার সময় পাবেন?


339

আমি একটি স্ক্রিপ্টের সমাপ্তির সময় প্রদর্শন করতে চাই।

আমি বর্তমানে যা করছি তা হ'ল -

#!/bin/bash
date  ## echo the date at start
# the script contents
date  ## echo the date at end

এটি কেবল স্ক্রিপ্টের শুরু এবং শেষের সময়। প্রসেসরের সময় / io সময় ইত্যাদির মতো সূক্ষ্ম দানাদার আউটপুট প্রদর্শন করা কি সম্ভব হবে?



আমি মনে করি অস্থায়ী ওঠানামার কারণে বর্তমান গৃহীত উত্তরটি সত্যই যথেষ্ট নয়।
লিও লোপোল্ড হার্টজ 준영

1
@ সিরোস্যান্টিলি 事件 事件 ২০১六四 六四 事件 法轮功 আমি মনে করি যে আপনার প্রস্তাবিত থ্রেড এখনও সাময়িক ঘটনার প্রভাবটি দূর করতে যথেষ্ট নয়।
লিও লোপল্ড হার্টজ 준영

এছাড়াও সম্পর্কিত: stackoverflow.com/questions/5152858/... বা কিছুটা unix.stackexchange.com/questions/334145/...
phk

একটি কমান্ড রয়েছে যা আপনি চালাতে পারেন এবং তারপরে এটি সমস্ত ইউনিক্স কমান্ডগুলি স্বয়ংক্রিয়ভাবে বার করে, কীভাবে সক্ষম করতে ভুলে গেছে?
পাউডার366

উত্তর:


448

timeআপনি স্ক্রিপ্ট কল করার সময় কেবল ব্যবহার করুন :

time yourscript.sh

61
এই তিনবার আউটপুট: real, userএবং sys। এর অর্থের জন্য এখানে দেখুন
গ্যারেট

27
এবং "আসল" সম্ভবত লোকেরা জানতে চায় - "রিয়েল হ'ল দেয়ালের ঘড়ির সময় - কলটি শুরু থেকে শেষের সময়"
ব্র্যাড পার্কস

3
Stdout একটি ফাইল মধ্যে ক্যাপচার উপায় আছে? উদাহরণস্বরূপ, এর মতো কিছুtime $( ... ) >> out.txt
জন

1
এছাড়াও আপনি কমান্ড লাইন কমান্ড ক্রমের এই করতে পারেন, যেমন:time (command1 && command2)
meetar

1
অথবা তিনি তাঁর স্ক্রিপ্টে কেবল এটি করতে পারেন: প্রতিধ্বনিত $ এটিকে বাশ বলে মনে করছেন
ক্রসফিট_আর_বিয়ার

169

যদি timeকোনও বিকল্প না হয়,

start=`date +%s`
stuff
end=`date +%s`

runtime=$((end-start))

30
মনে রাখবেন যে এটি কেবল তখনই কাজ করে যদি আপনার সাব-সেকেন্ড যথার্থতার প্রয়োজন হয় না। কিছু ব্যবহারের জন্য যা গ্রহণযোগ্য হতে পারে, অন্যদের পক্ষে তা নয়। একটু ভালো স্পষ্টতা (আপনি এখনও invoking থাকবেন dateদুইবার, উদাহরণস্বরূপ, তাই আপনি এ পারে শ্রেষ্ঠ বাস্তবে মিলিসেকেন্ডে স্পষ্টতা পেতে, এবং সম্ভবত কম), ব্যবহার করার চেষ্টা করুন date +%s.%N। ( %Nপুরো দ্বিতীয় থেকে ন্যানোসেকেন্ডস।)
সিভিএন

ভাল যুক্তি. আমি কিবোর্ড ছেড়ে যাওয়ার পরে তা ভেবেছিলাম কিন্তু ফিরে আসেনি। ^^ এছাড়াও মনে রাখবেন, ওপি, সেই "তারিখ" নিজেই রান সময়টিতে কয়েক মিলিসেকেন্ড যুক্ত করবে।
রব বোস

2
পছন্দ করুন এটি ভাল নির্দেশ করে; ব্যাশ পাটিগণিতের সম্প্রসারণ কেবলমাত্র পূর্ণসংখ্যা। আমি দুটি সুস্পষ্ট বিকল্প দেখতে পাচ্ছি; হয় তারিখের বিন্যাসের স্ট্রিংয়ে পিরিয়ডটি খনন করুন (এবং ফলাফলটি প্রথম যুগের পরে থেকে ন্যানোসেকেন্ড হিসাবে বিবেচনা করুন), সুতরাং jwchew এর পরামর্শ মতো দুটি মান থেকে আসল রানটাইম গণনা করার date +%s%Nমতো আরও কিছু সক্ষম ব্যবহার করুন বা ব্যবহার করুন bc। তবুও, আমি অনুভব করি যে এই পদ্ধতির এটি করার একটি suboptimal উপায়; timeউপরে বর্ণিত কারণগুলির জন্য, উপলভ্য থাকলে যথেষ্ট ভাল।
সিভিএন

10
কেবল ইনস্টল করুন bcএবং তারপরে এটি করুন:runtime=$( echo "$end - $start" | bc -l )
শে

10
যদি আপনার স্ক্রিপ্টটি বেশ কয়েক মিনিট সময় নেয় তবে ব্যবহার করুন:echo "Duration: $((($(date +%s)-$start)/60)) minutes
রুব 77

75

timesআপনার স্ক্রিপ্ট থেকে বেরিয়ে আসার জন্য কেবল যুক্তি ছাড়াই কল করুন ।

সঙ্গে kshবা zsh, এছাড়াও আপনি ব্যবহার করতে পারেন timeপরিবর্তে। এর সাথে zsh, ব্যবহারকারী এবং সিস্টেম সিপিইউ সময় timeছাড়াও প্রাচীর ঘড়ির সময় আপনাকে দেবে ।

আপনার স্ক্রিপ্টের প্রস্থান স্থিতি সংরক্ষণ করতে, আপনি এটি করতে পারেন:

ret=$?; times; exit "$ret"

অথবা আপনি এতে একটি ফাঁদ যোগ করতে পারেন EXIT:

trap times EXIT

এইভাবে, যখনই শেলটি প্রস্থান করে এবং প্রস্থান স্থিতি সংরক্ষণ করা হবে তখন সময়গুলি কল করা হবে।

$ bash -c 'trap times EXIT; : {1..1000000}'
0m0.932s 0m0.028s
0m0.000s 0m0.000s
$ zsh -c 'trap time EXIT; : {1..1000000}'
shell  0.67s user 0.01s system 100% cpu 0.677 total
children  0.00s user 0.00s system 0% cpu 0.677 total

এছাড়াও লক্ষ করুন যে সমস্ত bash, kshএবং zshএকটি $SECONDSবিশেষ চলক রয়েছে যা প্রতি সেকেন্ডে স্বয়ংক্রিয়ভাবে বৃদ্ধি পায় mented উভয় zshএবং ksh93, সেই পরিবর্তনশীলটিকে typeset -F SECONDSআরও স্পষ্টতা পেতে ভাসমান পয়েন্ট (সহ )ও তৈরি করা যেতে পারে । এটি কেবল প্রাচীর ঘড়ির সময়, সিপিইউ সময় নয়।


12
সেই CO সেকেন্ডস ভেরিয়েবলটি খুব দরকারী, ধন্যবাদ!
andybuckley

আপনার দৃষ্টিভঙ্গি কী অস্থায়ী ঘটনাগুলির প্রভাবকে সরিয়ে দেয়? - - আমি মনে করি আপনার পদ্ধতির কাছাকাছি timeপদ্ধতির আগে উপস্থাপিত। - - আমি মনে করি timeitম্যাটল্যাব কোডে উপস্থাপিত পদ্ধতিটি এখানে কার্যকর হতে পারে।
লিও লোপোল্ড হার্টজ 준영

2
হাই, @ স্টাফেন চেজেলাস আমি খুঁজে পেয়েছি timesদেয়াল সময় দেয় না, তাই না? উদাহরণস্বরূপ,bash -c 'trap times EXIT;sleep 2'
ব্যবহারকারী 15964


32

ব্যান্ডওয়্যাগনের জন্য আমি কিছুটা দেরি করেছি, তবে অনুসন্ধানের মাধ্যমে অন্যরা যদি এই থ্রেডে হোঁচট খায় তবে আমার সমাধান পোস্ট করতে চেয়েছিলেন (সাব-সেকেন্ড যথার্থতার জন্য)। আউটপুট দিন, ঘন্টা, মিনিট এবং অবশেষে সেকেন্ডের বিন্যাসে রয়েছে:

res1=$(date +%s.%N)

# do stuff in here

res2=$(date +%s.%N)
dt=$(echo "$res2 - $res1" | bc)
dd=$(echo "$dt/86400" | bc)
dt2=$(echo "$dt-86400*$dd" | bc)
dh=$(echo "$dt2/3600" | bc)
dt3=$(echo "$dt2-3600*$dh" | bc)
dm=$(echo "$dt3/60" | bc)
ds=$(echo "$dt3-60*$dm" | bc)

printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds

আশা করি সেখানে কেউ এই দরকারী খুঁজে পেয়েছেন!


1
আমার ধারণা, গণনাগুলি করতে 'বিসি' ব্যবহার করা ছাড়া আর কোনও (কেবল বাশ) উপায় নেই।
বিটিডব্লিউ

1
সাবধান থাকুন যে ফ্রিবিএসডি dateসাব-সেকেন্ড নির্ভুলতা সমর্থন করে না এবং Nটাইমস্ট্যাম্পে কেবল আক্ষরিক " " যুক্ত করবে ।
আন্তন স্যামসনভ

1
খুব সুন্দর স্ক্রিপ্ট, তবে আমার ব্যাশ সাবসকন্ড অংশটি পরিচালনা করে না। আমি আরও শিখেছি, বিসি-তে 1 / কার্যকরভাবে কার্যকরভাবে স্ট্রিপ করে, তাই আমি @ / 1 @ কে $ ডিএস গণনাতে যুক্ত করেছি, এবং এটি এখন খুব সুন্দর স্টাফ প্রদর্শন করে!
ড্যানিয়েল

1
খ্রিস্টপূর্ব মডিউল সমর্থন করে: dt2=$(echo "$dt%86400" | bc)। শুধু বলছি ... বিটিডাব্লু আমি ফর্মটি পছন্দ করি dt2=$(bc <<< "${dt}%86400")তবে এটি সম্পূর্ণ ব্যক্তিগত।
দানি_ল

16

আমার পদ্ধতি bash:

# Reset BASH time counter
SECONDS=0
    # 
    # do stuff
    # 
ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"

এটি অতিবাহিত সময় দেখায়, তবে এটি "প্রসেসরের সময়, I / O সময় মত সূক্ষ্ম দানাদার আউটপুট" দেখাচ্ছে না।
রোয়াইমা

3
উত্থাপিত হিসাবে প্রশ্নের উত্তর খুঁজছেন যারা এই সমাধানটি দরকারী বলে মনে করছেন। আপনার মন্তব্যটি ওপিএস প্রশ্নের আরও ভালভাবে সম্বোধন করা হবে।
চিহ্নিত করুন

5
#!/bin/bash
start=$(date +%s.%N)

# HERE BE CODE

end=$(date +%s.%N)    
runtime=$(python -c "print(${end} - ${start})")

echo "Runtime was $runtime"

হ্যাঁ, এটি পাইথনকে কল করে তবে আপনি যদি এটির সাথে বেঁচে থাকতে পারেন তবে এটি বেশ দুর্দান্ত, প্রসারযুক্ত সমাধান।


5
সাবধান থাকুন যে pythonকমান্ডটি সাবসেলে চালাচ্ছেন এবং এর আউটপুটটি পড়তে বেশিরভাগ বর্তমান সিস্টেমে কয়েক মিলিয়ন ন্যানো সেকেন্ড লাগবে। চলমান জন্য একই date
স্টাফেন চেজেলাস

7
"কয়েক মিলিয়ন ন্যানোসেকেন্ড" হ'ল কয়েক মিলিসেকেন্ড। লোকেদের টাইম করা বাশ স্ক্রিপ্টগুলি সাধারণত সে সম্পর্কে খুব বেশি উদ্বিগ্ন হয় না (যদি না তারা মেগাসেকেন্ডে কয়েক বিলিয়ন স্ক্রিপ্ট চালায়)।
জিল্ক

2
এটিও লক্ষ করুন, গণনাটি একটি অজগর প্রক্রিয়ার অভ্যন্তরে করা হয়ে গেলেও পাইথন আহরণের আগে মানগুলি সম্পূর্ণরূপে সংগ্রহ করা হয়েছিল। "মিলিয়ন ন্যানোসেকেন্ডস" ওভারহেড ছাড়াই স্ক্রিপ্টটির সম্পাদনের সময়টি সঠিকভাবে পরিমাপ করা হবে।
ভিক্টর শ্রড্ডার

5

এই প্রশ্নটি বেশ পুরানো তবে এটি করার আমার পছন্দের উপায়টি অনুসন্ধানের চেষ্টা করে এই থ্রেডটি উপরে উঠে এসেছিল ... এবং আমি অবাক হয়েছি যে এটির কথা কেউ উল্লেখ করেনি:

perf stat -r 10 -B sleep 1

'পারফ' একটি কার্যকারিতা বিশ্লেষণকারী সরঞ্জাম যা 'সরঞ্জাম / পারফ' এর অধীনে কার্নেলের অন্তর্ভুক্ত এবং প্রায়শই পৃথক প্যাকেজ হিসাবে ইনস্টল করতে পাওয়া যায় (সেন্টোজে 'পারফ' এবং দেবিয়ান / উবুন্টুতে 'লিনাক্স-সরঞ্জাম')। লিনাক্স কার্নাল পারফ উইকির এটি সম্পর্কে আরও অনেক তথ্য রয়েছে।

'পারফ স্ট্যাট' চালনা শেষে ঠিক সময়ে কার্যকর কার্যকর সময় সহ বেশ কিছু বিশদ বিবরণ দেয়:

1.002248382 seconds time elapsed                   ( +-  0.01% )

2
কী perf?
বি লেয়ার

@ বি স্তর - 'পারফ' এর সংক্ষিপ্ত বিবরণ দেওয়ার জন্য আমার উত্তর সম্পাদনা করেছে।
জাহিদ

1
perf statএখন "আপনার কাছে স্ট্যাটাস সংগ্রহের অনুমতি নাও থাকতে পারে" সম্পর্কে অভিযোগ। আপনি যদি কোনও কমান্ড চালনা না করেন তবে sudoএটি এমন পরিস্থিতিতে সমস্ত ক্ষেত্রে অকেজো করে তোলে যেখানে আপনি সম্পূর্ণরূপে নিজের লক্ষ্য মেশিনের মালিক নন।
আলমার

4

একটি ছোট শেল ফাংশন যা তাদের সময় মাপার জন্য কমান্ডগুলির আগে যুক্ত করা যেতে পারে:

tm() {
  s=$(date +%s)
  $@
  rc=$?
  echo "took $[$(date +%s)-$s] seconds. return code $rc" >&2
  return $rc
}

তারপরে এটি আপনার স্ক্রিপ্টে বা আপনার কমান্ড লাইনে ব্যবহার করুন:

tm the_original_command with all its parameters

এটি মিলিসেকেন্ড যুক্ত করার উপযুক্ত হবে, চেষ্টা করেও s=$(date +%s000), এটি কাজ করে কিনা তা নিশ্চিত নয়।
loretoparisi

3

এখানে অ্যালেক্সের উত্তরের একটি বৈচিত্র। আমি কেবল কয়েক মিনিট এবং সেকেন্ডের বিষয়ে যত্নশীল, তবে আমি এটি অন্যরকমভাবেও ফর্ম্যাট করতে চেয়েছিলাম। সুতরাং আমি এটি করেছি:

start=$(date +%s)
end=$(date +%s)
runtime=$(python -c "print '%u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)")

1
ডাউনটা কেন? আমার কি বাগ আছে?
এমপন্টিলো

3
#!/bin/csh
#PBS -q glean
#PBS -l nodes=1:ppn=1
#PBS -l walltime=10:00:00
#PBS -o a.log
#PBS -e a.err
#PBS -V
#PBS -M shihcheng.guo@gmail.com
#PBS -m abe
#PBS -A k4zhang-group
START=$(date +%s)
for i in {1..1000000}
do
echo 1
done
END=$(date +%s)
DIFF=$(echo "$END - $START" | bc)
echo "It takes DIFF=$DIFF seconds to complete this task..."

7
ইতিমধ্যে প্রদত্ত অন্যান্য উত্তরগুলির থেকে এটি কীভাবে আলাদা? যা dateস্ক্রিপ্টের আগে এবং পরে ব্যবহার করে এবং তাদের মধ্যে পার্থক্যটি আউটপুট করে?
এরিক রেনোফ

2

ব্যবহার কেবল বাশ করে শেল স্ক্রিপ্টের একটি অংশের (বা পুরো স্ক্রিপ্টের জন্য বিচ্ছিন্ন সময়) সময়কাল পরিমাপ করা এবং গণনা করা সম্ভব :

start=$SECONDS

... # do time consuming stuff

end=$SECONDS

আপনি এখন কেবল পার্থক্য মুদ্রণ করতে পারেন:

echo "duration: $((end-start)) seconds."

আপনার যদি কেবল বর্ধিত সময়কাল প্রয়োজন হয় তবে:

echo "duration: $((SECONDS-start)) seconds elapsed.."

আপনি সময়কটি একটি চলকতেও সঞ্চয় করতে পারেন:

let diff=end-start

IS এটি উত্তর ভাবেন। বা আরও সহজভাবে: CO শেষে SECONDS। এটি একটি বিল্ট-ইন ব্যাশ ভেরিয়েবল। অন্যান্য সমস্ত উত্তর কেবল এই চাকাটি পুনরায় উদ্ভাবনের জন্য অতিরিক্ত কাজ করছে ...
ক্রসফিট_আর_বিয়ার

2

ব্যক্তিগতভাবে, আমি আমার স্ক্রিপ্ট কোডটি কিছু "প্রধান" ফাংশনে এমনভাবে গুটিয়ে রাখতে চাই:

main () {
 echo running ...
}

# stuff ...

# calling the function at the very end of the script
time main

timeএই পরিস্থিতিতে কমান্ডটি ব্যবহার করা কত সহজ তা লক্ষ্য করুন । স্পষ্টতই আপনি স্ক্রিপ্ট পার্স সময় সহ সুনির্দিষ্ট সময়টি পরিমাপ করছেন না তবে বেশিরভাগ পরিস্থিতিতে আমি এটি যথেষ্ট সঠিক খুঁজে পেয়েছি।


1
#!/bin/bash
begin=$(date +"%s")

Script

termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."

1

টাইমিং ফাংশন উপর ভিত্তি করে SECONDS, কেবলমাত্র দ্বিতীয় স্তরের গ্রানুলারিটির মধ্যে সীমাবদ্ধ, কোনও বাহ্যিক আদেশ ব্যবহার করে না:

time_it() {
  local start=$SECONDS ts ec
  printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
  printf '%s\n' "$ts Starting $*"
  "$@"; ec=$?
  printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
  printf '%s\n' "$ts Finished $*; elapsed = $((SECONDS-start)) seconds"
  # make sure to return the exit code of the command so that the caller can use it
  return "$ec"
}

উদাহরণ স্বরূপ:

time_it sleep 5

দেয়

2019-03-30_17:24:37 Starting sleep 5 2019-03-30_17:24:42 Finished
sleep 5; elapsed = 5 seconds
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.