2010-10-13 15 views
15

के लिए संघर्ष करना मैं बैश में टाइम कमांड के आउटपुट को पार्स करने के लिए संघर्ष कर रहा हूं - और इसे कॉल करने पर इसे आउटपुट प्रिंट करने से रोकने के लिए भी।पार्स (बैश) टाइम कमांड

#!/bin/bash 
TIME=`time ls -lh > /dev/null` 
echo "Testing..." 
echo $TIME 

यह वर्तमान में बाहर प्रिंट:

{blank-line} 
real 0m0.064s 
user 0m0.002s 
sys  0m0.005s 
Testing 
{blank-line} 

इसलिए, यह $TIME करने के लिए सौंपा मूल्य की तरह लगता है समय प्रिंट-आउट के शुरू में रिक्त पंक्ति है यह मेरा परीक्षण कोड है। मुझे sys लाइन के सेकंड मान पर जाना होगा - यानी, "0.005"। मुझे गारंटी है कि मेरे पास केवल सेकंड होंगे, इसलिए मुझे "एम" से पहले कुछ भी चाहिए नहीं है - हालांकि, सेकेंड भाग xx.xxx के रूप में हो सकता है यदि यह> = 10 सेकंड हो जाता है। मुझे वर्तमान में कोई समय नहीं है कि 'टाइम' आउटपुट को दबाने के लिए, रिक्त रेखा के बजाय इसे कैप्चर करें, न ही मुझे आवश्यक मान प्राप्त करने के लिए इसका विश्लेषण करें।

किसी भी मदद की बहुत सराहना की जाएगी ...

उत्तर

16

आप builtin time बैश का उपयोग करते हैं, तो आप TIMEFORMAT चर सेट करके इसके उत्पादन को नियंत्रित कर सकते हैं:

TIMEFORMAT=%R 

और आप के बाद से है कि केवल उत्पादन संख्या के लिए time कारण होगा कोई भी पार्सिंग करने की जरूरत नहीं होगी सेकंड का

और इस का उपयोग करें:

echo "Testing..." 
TIME=$({ time ls -lh > /dev/null; } 2>&1) 
echo $TIME 

या BashFAQ/032 से अन्य तकनीकों में से एक।

1

time आदेश आउटपुट STDERR है, जो आप पर कब्जा करने या पुन: निर्देशित नहीं कर रहे हैं करने के लिए समय जानकारी। तो असाइनमेंट का समय, वह जानकारी आपके कंसोल पर मुद्रित की जाती है, जबकि $TIME वैरिएबल को कमांड का STDOUT मिलता है - जिसे आपने /dev/null पर रीडायरेक्ट किया है, इसलिए यह खाली है।

शायद आपको आदेश के STDERR को कैप्चर करने का प्रयास करना चाहिए?

+0

आह, मैं 'STDERR' को उस समय उत्पादन का एहसास नहीं था। मैं उस समय '$ TIME' चर में कैप्चर कैसे करूं? – Stephen

7

सबसे पहले, डेटा आप पर कब्जा करने की कोशिश कर रहे हैं मानक त्रुटि के लिए लिखा जा रहा है। लेकिन इस मामले में उस आउटपुट को कैप्चर करना काफी मुश्किल है।

time दोनों निष्पादन योग्य (/usr/bin में) साथ ही साथ बैश और अन्य गोले में अंतर्निहित शेल कमांड भी है। जब आप /usr/bin/time निर्दिष्ट किए बिना time निष्पादित, आप पार्टी में निर्मित एक कमांड को क्रियान्वित कर रहे हैं। यह आउटपुट के साथ चीजों को करना मुश्किल बनाता है, क्योंकि बैश इसे सामान्य कार्यक्रम की तरह नहीं मानता है; यह बैश द्वारा लिखित एक विशेष अंतर्निहित फ़ंक्शन है।

यह जानकर, और time(1) के लिए मैन पेज को देखकर, मैं देख सकता हूं कि जिस डेटा को आप time से कैप्चर करने का प्रयास कर रहे हैं, उसे stderr पर आउटपुट किया गया है। तो इस के लिए मेरे वैकल्पिक हल सीधे /usr/bin/time निष्पादित करने के लिए इस प्रकार है: मानक बाहर करने के लिए

TIME=`/usr/bin/time ls -lh 2>&1 >/dev/null` 

यह प्रतियां मानक त्रुटि धारा, और फिर पुनर्निर्देश जो सामान्य रूप से /dev/null के लिए बाहर मानक को जाता है। मानक त्रुटि, हालांकि, अभी भी मानक आउट हो जाएगी क्योंकि इसे पुनर्निर्देशन से पहले डुप्लिकेट किया गया था। इनके क्रम को उलटना काम नहीं करेगा। (हाँ, यह भ्रामक है।)

दुर्भाग्य से, /usr/bin/time थोड़ा इसके उत्पादन में कम सटीक है:

0.00 real   0.00 user   0.00 sys 

वैकल्पिक रूप से, आप 2 उप गोले का उपयोग कर सकते हैं, इस प्रकार है:

TIME=$((time ls -lh >/dev/null) 2>&1) 

यह पहले के भीतर दूसरे सबहेल पर मानक त्रुटि के लिए लिखा गया है, जो आपको आउटपुट कैप्चर करने की अनुमति देता है, फिर से लिख देगा। सब-शैल पर अधिक के लिए http://www.tldp.org/LDP/abs/html/subshells.html देखें।

+0

या केवल एक उप-खोल का उपयोग 'TIME =" $ ({time ls -lh>/dev/null;} 2> और 1) के रूप में करें –

0

मैं इसे एक टिप्पणी के रूप में पोस्ट करना चाहता था, लेकिन यह बहुत लंबा होगा। मैं डेटा प्राप्त करने के लिए एक और थोड़ा अलग तरीका पेश करना चाहता था।

निष्पादन के समय को प्राप्त करने के लिए /usr/bin/time के बजाय का उपयोग करके स्ट्रीम के रूप में समय के आउटपुट प्राप्त करने के लिए आप दो उप-शैल का उपयोग कर सकते हैं। मुझे लगता है कि आप को /usr/bin/time के साथ यहां स्थानांतरित कर सकते हैं।

$ ((time ./print_test.sh > deleteme) 2>&1) > deletemetime 

$ cat deleteme 
test 

$ cat deletemetime 
./print_test.sh > deleteme 0.00s user 0.00s system 86% cpu 0.003 total 

$ ((time ./print_test.sh > deleteme) 2>&1) | sed 's/system/kernel/' 
./print_test.sh > deleteme 0.00s user 0.00s kernel 86% cpu 0.003 total 

ध्यान दें कि आउटपुट उत्पन्न करने के तरीके में एक अंतर दिखाई देता है। कभी कभी यह है कि प्रारूप में है और कभी कभी यह इस प्रारूप में:

real 0m0.420s 
user 0m0.385s 
sys  0m0.040s 

इस बिंदु पर सुनिश्चित नहीं हैं कि एक ही रास्ता या अन्य निर्धारित करता है।

बेशक, आप उदाहरण का उपयोग कर सकते हैं

TIMEFORMAT='%3R' 

प्रारूप को ठीक करने के लिए।

2

हालांकि समाधान एक ही तर्क के आसपास मंडराना, लेकिन अभी भी मैं निम्नलिखित सूचीबद्ध नहीं मिल सकता है, तो समाधान का एक और संस्करण:

TIME=$(time (ls -lh >/dev/null) 2>&1) 
संबंधित मुद्दे