फ़ाइल में `टाइम` का आउटपुट लिखें, कोष्ठक की आवश्यकता क्यों है?


18

timeलिखता है stderr, इसलिए कोई यह मान लेगा कि 2>&1कमांड लाइन में जोड़ने से इसका आउटपुट रूट होना चाहिए stdout। लेकिन यह काम नहीं करता है:

test@debian:~$ cat file 
one two three four
test@debian:~$ time wc file > wc.out 2>&1

real    0m0.022s
user    0m0.000s
sys     0m0.000s
test@debian:~$ cat wc.out 
 1  4 19 file

केवल कोष्ठक के साथ यह काम करता है:

test@debian:~$ (time wc file) > wc.out 2>&1
test@debian:~$ cat wc.out 
 1  4 19 file

real    0m0.005s
user    0m0.000s
sys     0m0.000s

इस मामले में कोष्ठक की आवश्यकता क्यों है? एक एकल आदेश के time wcरूप में व्याख्या क्यों नहीं की जाती है ?


3
ध्यान दें कि परिणाम timeशेल कीवर्ड, या के आधार पर अलग-अलग होंगे /usr/bin/time। यहां शामिल किए गए विवरणकर्ताओं के कई सेट हो सकते हैं (शेल का, और timeप्रक्रिया से जुड़े लोग )। और चलो ()उपधारा द्वारा निहित के बारे में मत भूलना । ( बैश विशेषज्ञ की प्रतीक्षा में : p)
जॉन डब्ल्यूएच स्मिथ

जवाबों:


24

में ksh, bashऔर zsh, timeएक कमांड (बिलिन या नहीं) नहीं है, यह भाषा में आरक्षित शब्द है जैसे forया while

इसका उपयोग पाइपलाइन 1 के समय के लिए किया जाता है ।

में:

time for i in 1 2; do cmd1 "$i"; done | cmd2 > redir

आपके पास विशेष सिंटैक्स है जो शेल को उस पाइप लाइन को चलाने के लिए कहता है:

for i in 1 2; do cmd1 "$i"; done | cmd2 > redir

और इसके लिए समय आँकड़ों की रिपोर्ट करें।

में:

time cmd > output 2> error

यह वही है, तो आप कर रहे हैं समयcmd > output 2> error आदेश, और समय आंकड़े अभी भी खोल के stderr पर चलते हैं।

आप की जरूरत है:

{ time cmd > output 2> error; } 2> timing-output

या:

exec 3>&2 2> timing-output
time cmd > output 2> error 3>&-
exec 2>&3 3>&-

शेल के स्टडर के लिए timing-outputसमय के निर्माण से पहले पुनर्निर्देशित किया जाना चाहिए (फिर से, कमांड नहीं ) का उपयोग किया जाता है (यहां समय के लिए cmd > output 2> error 3>&-)।

आप उस timeनिर्माण को एक उप- भाग में भी चला सकते हैं जिसमें उसका स्टैडर पुनर्निर्देशित है:

(time cmd > output 2> error) 2> timing-output

लेकिन यहां उप-धारा आवश्यक नहीं है, आपको केवल उस समय पुनर्निर्देशित होने के लिए stderr की आवश्यकता होती है जब timeनिर्माण को लागू किया जाता है।

अधिकांश सिस्टम में एक timeकमांड भी है । आप timeकीवर्ड को अक्षम करके उसको लागू कर सकते हैं । आपको बस उस कीवर्ड को किसी भी तरह से उद्धृत करना होगा क्योंकि कीवर्ड केवल तभी पहचाने जाते हैं जैसे कि शाब्दिक।

'time' cmd > output 2> error-and-timing-output

लेकिन सावधान रहें प्रारूप भिन्न हो सकता है और दोनों का स्टाडर timeऔर cmdविलीन हो जाएगा error-and-timing-output

इसके अलावा, निर्माण के timeविपरीत आदेश, timeसमय पाइपलाइनों या यौगिक आदेशों या कार्यों या शेल बिल्डिंस नहीं कर सकता ...

यदि यह एक अंतर्निहित कमांड था, तो यह समय पर इनवोकेशन या बिल्डिंस को कार्य करने में सक्षम हो सकता है, लेकिन यह समय पुनर्निर्देशन या पाइपलाइन या कंपाउंड कमांड नहीं कर सकता है।


1 ध्यान दें कि bash(क्या माना जा सकता है) एक बग जिससे time (cmd) 2> file(लेकिन time cmd | (cmd2) 2> fileउदाहरण के लिए नहीं ) समय आउटपुट को पुनर्निर्देशित करता हैfile


खैर, मैं अक्सर अपने सिर को याद रखने के लिए जोर देता हूं कि timeयह एक कीवर्ड है, शेल शेलिन नहीं।
कोउन्ग्लम

'time'निष्पादन योग्य पाने के लिए उपयोग करने के बारे में टिप के लिए धन्यवाद - लेखन /usr/bin/time(या यहां तक ​​कि command time:-)) की तुलना में आसान ।
एलेक्सिस

@alexis भी \time
ctrl-alt-delor

7

नाम का कोई आदेश नहीं है time wc, timeऔर शेल में wcअलग शब्द हैं ।

अब, अक्सर नाम के दो अलग-अलग कार्यक्रम होते हैंtime , एक शेल कीवर्ड है, दूसरा एक बाहरी कमांड है । शेल में, जो timeशेल कीवर्ड है, जब आप टाइप करते हैं time wc ..., तो शेल timeबाहरी समय की उपयोगिता के बजाय अपने कीवर्ड का उपयोग करता है

जब शेल timeकीवर्ड का उपयोग करता है , तो उसे नई प्रक्रिया के लिए कांटा () की आवश्यकता नहीं होती है , वर्तमान timeमानक और मानक त्रुटि को बदला नहीं जाता है। पुनर्निर्देशन में हिस्सा:

time wc file > wc.out 2>&1

wcकेवल प्रभावित करता है ।

जब आप कंपाउंड कमांड का(list) उपयोग करते हैं :

(time wc file) > wc.out 2>&1

शेल time wc fileएक उप-प्रकार के अंदर चलता (time wc file)था , एक एकल आदेश माना जाता था , और पुनर्निर्देशन का हिस्सा इसके मानक आउटपुट और मानक त्रुटि को प्रभावित करता है, जिसमें अब timeऔर शामिल हैं wc


आप एक ही प्रभाव बना सकते हैं, समूहन कमांड के किसी अन्य रूप का उपयोग करके नई प्रक्रिया को बनाने की लागत के बिना {list;}:

{time wc file;} > wc.out 2>&1

यदि आप बाहरी उपयोग करते हैं time, तो आप इस समस्या का सामना नहीं करते हैं, क्योंकि यह नई प्रक्रिया में चलाया गया था:

/usr/bin/time wc file > wc.out 2>&1

क्या उपयोग करने timeऔर के बीच कोई व्यावहारिक अंतर है /usr/bin/time? क्या निष्पादकों को कार्यात्मक रूप से समान कहा जा रहा है?
हाशिम

2

क्योंकि timeआप निष्पादित कर रहे हैं बैश बिलिन। बैश इसे ऐसे विशेष तरीके से संसाधित करता है।

यदि आप वास्तविक timeद्विआधारी का उपयोग करेंगे , तो यह ठीक उसी तरह से कार्य करेगा जैसे आप इसकी अपेक्षा करते हैं:

/usr/bin/time wc file > wc.out 2>&1

हालांकि इस बार का आउटपुट थोड़ा अलग है:

 $ /usr/bin/time wc file > wc.out 
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata1900maxresident)k
0inputs+8outputs (0major+82minor)pagefaults 0swaps

9
यदि यह एक बिल्डिन था, तो यह एक समस्या नहीं होगी। समस्या यह है कि यह भाषा में एक कीवर्ड है। time cmd > outputसमय cmd > output, और time foo | barसमय foo | bar
स्टीफन चेज़लस

1

ऐसा नहीं है timeकि समय की जानकारी लिखते हैं। timeकमांड पूरा हो जाने के बाद, बिल्‍ड इसे शेल लिखता है। लेकिन पुनर्निर्देशन केवल कमांड को प्रभावित करता है।

में (time ...)मामला पुनर्निर्देशन पूरे subshell लिए आवेदन किया है।


0

क्योंकि समय एक खोल builtin है, यह करने के लिए लिखते हैं खोल नहीं बल्कि आदेश के stderr से की stderr,।

कोष्ठक का उपयोग पूरे आदेश को एक बच्चे के खोल में मजबूर करता है जिसका स्टैडर पुनर्निर्देशित किया जा सकता है।

घुंघराले कोष्ठक का उपयोग वास्तव में एक उपखंड शुरू करने के बिना एक समान परिणाम पैदा करता है

  { time who ; } > /tmp/timwho >& /tmp/xx 

(हाँ, आपको अर्धविराम की आवश्यकता है)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.