बैश में एक चर में यूनिक्स में समय कमांड के पुनर्निर्देशित आउटपुट?


13

मैं सिर्फ एक टाइम कमांड के आउटपुट को कैप्चर करना चाहता हूं:

X=$(time ls)

या

$(time ls) | grep real

समय फ़ंक्शन इसे कंसोल पर थूकता है, हालांकि। मैं यह कैसे करु?

जवाबों:


12

एक्स = `(समय एलएस) 2> और 1 | grep असली `


आप के लिए सिर्फ एक उपधारा की जरूरत नहीं है time; उस संबंध में डेनिस विलियमसन का जवाब बेहतर है।
21

11

बाशफा / ०३२ देखें ।

$ # captures output of command and time
$ time=$( TIMEFORMAT="%R"; { time ls; } 2>&1 )    # note the curly braces

$ # captures the time only, passes stdout through
$ exec 3>&1 4>&2
$ time=$(TIMEFORMAT="%R"; { time ls 1>&3 2>&4; } 2>&1)
bar baz
$ exec 3>&- 4>&-

समय "0.000" का उपयोग TIMEFORMAT="%R"करेगा, जो "वास्तविक" समय होगा।


क्या आप थोड़ा समझा सकते हैं कि यह कैसे काम करता है? मैंने वर्षों से इस कार्गो पंथ शैली की तरह एक स्निपेट का उपयोग किया है। Whats धारा 3 और 4? और यह '-' ?
सेरेक्स

1
@ साइरेक्स: स्ट्रीम 3 और 4 धाराएं execउपलब्ध फ़ाइल डिस्क्रिप्टर का उपयोग करके मेरे उत्तर में कमांड द्वारा बनाई गई हैं । किसी भी उपलब्ध फ़ाइल विवरणक का उपयोग किया जा सकता है। धारा 3 और 4 क्रमशः 1 ( stdout) और 2 ( stderr) की प्रतियां हैं। इस के उत्पादन की अनुमति देता है lsके लिए सामान्य रूप से पारित करने के लिए stdoutऔर stderrजबकि के उत्पादन में 3 और 4 के माध्यम से time(जो आम तौर जाता है stderr) मूल पर भेज दिया जाएगा stdout(1) और फिर आदेश प्रतिस्थापन का उपयोग कर चर में कब्जा कर लिया। तुम मेरे उदाहरण में देख सकते हैं, फ़ाइल नाम barऔर bazटर्मिनल के लिए उत्पादन कर रहे हैं। ...
अगली सूचना तक रोक दिया गया।

1
... एक बार समाप्त होने के बाद, अतिरिक्त धाराओं का उपयोग करके बंद कर दिया जाता है -
अगली सूचना तक रोक दिया गया।

4

समय STDER के बजाय STDERR को अपना आउटपुट लिखता है। मामलों को बदतर बनाना, डिफ़ॉल्ट रूप से 'समय' एक शेल बिल्ड कमांड है, इसलिए यदि आप 'समय 2> & 1' का प्रयास करते हैं '2> और 1' केवल 'ls' पर लागू होता है।

समाधान शायद कुछ इस तरह होगा:

/usr/bin/time -f 'real %e' -o OUTPUT_FILE ls > /dev/null 2>&1<br>
REALTIME=$(cat OUTPUT_FILE | cut -f 2 -d ' ')

इसे करने के लिए अधिक फैंसी तरीके हैं, लेकिन यह स्पष्ट / सरल तरीका है।


मैं इस बिना -o करने में दिलचस्पी रखता हूं। क्या आप उन फैंसी तरीकों में से एक पोस्ट कर सकते हैं जो आप सोच रहे थे :)?
डेविड डोरिया

0

@ डेनिस विलियमसन का जवाब बहुत अच्छा है, लेकिन यह आपको कमांड के आउटपुट को एक वेरिएबल में और timeदूसरे वेरिएबल में आउटपुट को स्टोर करने में मदद नहीं करता है । फ़ाइल डिस्क्रिप्टर का उपयोग करके यह वास्तव में संभव नहीं है।

यदि आप रिकॉर्ड करना चाहते हैं कि किसी प्रोग्राम को चलाने में कितना समय लगता है, तो आप इसे अंतिम समय से प्रारंभ समय को घटाकर कर सकते हैं। यहाँ एक सरल उदाहरण है, जो दिखाता है कि एक कार्यक्रम को चलाने में कितने मिलीसेकंड में:

START_TIME=$(date +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(date +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"

यह timeकमांड के रूप में बिल्कुल सटीक नहीं है , लेकिन इसे अधिकांश बैश स्क्रिप्ट के लिए पूरी तरह से ठीक काम करना चाहिए।

दुर्भाग्य से मैक का dateकमांड %Nप्रारूप का समर्थन नहीं करता है , लेकिन आप स्थापित coreutils( brew install coreutils) और उपयोग कर सकते हैं gdate:

START_TIME=$(gdate +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(gdate +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.