हर आदेश के लिए एक 'जोड़ा' उर्फ ​​मजबूर


11

क्या हर कमांड में समयबद्ध उपनाम (इसे वाक्यांश करने के लिए एक बेहतर तरीके की कमी के लिए) जबरन जोड़ना संभव है bash?

उदाहरण के लिए, मैं एक विशिष्ट उपयोगकर्ता रखना चाहूंगा, जब भी कोई कमांड चलाया जाता है, तो इसे हमेशा या तो dateपहले और बाद में या उसके साथ लिपटा जाता है time

क्या यह संभव है और यदि ऐसा हो तो कैसे?


मैंने पहले देखा, और ऐसा करने का कोई तरीका नहीं खोज सका। जैसा कि कालेब कहते हैं, आप उपयोग कर सकते हैं preexec, लेकिन आप इसे preexec(जैसे preexec() { time $1; }) के अंदर नहीं चलाना चाहते , क्योंकि शेल preexecरिटर्न के बाद भी इसे चलाता है । तो सबसे अच्छा हम कुछ ऐसा ही कर सकते हैं।
मिकेल

@ मिकेल मुझे लगता है कि आप preexec()फ़ंक्शन का उपयोग कर सकते हैं वास्तव में आवरण जो भी कमांड को निष्पादित कर रहा था, उसे फ़ंक्शन के अंदर से खुद को चला रहा था, फिर किसी प्रकार की त्रुटि लौटाए ताकि शेल स्वयं कमांड को निष्पादित करने के लिए न जाए।
कालेब

जवाबों:


10

आप कमांड लाइन शुरू होने का समय रिकॉर्ड कर सकते हैं और जिस समय एक प्रॉम्प्ट प्रदर्शित होता है। बैश पहले से ही अपने इतिहास में प्रत्येक कमांड लाइन की शुरुआती तारीख का ट्रैक रखता है, और जब आप अगले प्रॉम्प्ट प्रदर्शित करते हैं, तो आप उस समय को नोट कर सकते हैं।

print_command_wall_clock_time () {
  echo Wall clock time: \
    $(($(date +%s) - $(HISTTIMEFORMAT="%s ";
                       set -o noglob;
                       set $(history 1); echo $2)))
}
PROMPT_COMMAND=print_command_wall_clock_time$'\n'"$PROMPT_COMMAND"

यह केवल आपको दूसरा प्रस्ताव देता है, और केवल दीवार घड़ी का समय। यदि आप बेहतर रिज़ॉल्यूशन चाहते हैं, तो आपको एक बाहरी dateकमांड का उपयोग करने की आवश्यकता है जो समय-समय पर कमांड को चलाने से पहले %Nनैनोसेकंड के लिए प्रारूप का समर्थन करता है, और DEBUGकॉल करने के लिए जाल date

call_date_before_command () {
  date_before=$(date +%s.%N)
}
print_wall_clock_time () {
  echo Wall clock time: \
    $((date +"$date_before - %s.%N" | bc))
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_command_wall_clock_time

DEBUGजाल के साथ भी , मुझे नहीं लगता कि प्रत्येक कमांड के लिए प्रोसेसर समय को स्वचालित रूप से प्रदर्शित करने का एक तरीका है, या शीघ्रता से अधिक भेदभाव करने वाला है।


यदि आप एक अलग शेल का उपयोग करने के लिए तैयार हैं, तो यहां बताया गया है कि zsh में प्रत्येक कमांड के लिए समय रिपोर्ट कैसे प्राप्त करें (यह अन्य कार्यों के लिए सामान्य नहीं है:

REPORTTIME=0

आप REPORTTIMEकिसी भी पूर्णांक मान पर सेट कर सकते हैं , समय की जानकारी केवल उन कमांडों के लिए प्रदर्शित की जाएगी जो प्रोसेसर समय के इस कई सेकंड से अधिक उपयोग करते हैं।

Zsh ने यह सुविधा csh से ली है जहाँ चर कहा जाता है time


3

यहां आपके विकल्प आपके शेल पर निर्भर करने वाले हैं। इसमें zshएक सुविधाजनक हुक फ़ंक्शन कहा जाता है preexec()जो किसी भी इंटरैक्टिव शेल कमांड से ठीक पहले चलाया जाता है। इस नाम के साथ एक फ़ंक्शन बनाकर, आप चीजों को निष्पादित कर सकते हैं। आप एक फ़ंक्शन के साथ भी अनुसरण कर सकते हैं precmd(), जिसे अगले प्रॉम्प्ट के तैयार होने से ठीक पहले चलाया जाएगा, जो आपके कमांड के पूरा होने के बाद सही होगा ।

इस फ़ंक्शन को बनाकर, आप जो भी आदेश चाहते हैं, उसके पहले और बाद में प्रॉम्प्ट पर जो भी आदेश जारी किए जा सकते हैं, आप कर सकते हैं। आप इसका उपयोग शेल उपयोग को लॉग करने, ताले बनाने, पर्यावरण का परीक्षण करने के लिए कर सकते हैं, या जैसा कि आपके उदाहरण में कमांड रन करते समय खर्च किए गए समय या संसाधनों की गणना करते हैं।

इस उदाहरण में, हम कमांड का उपयोग करने से पहले खुद को एक बेंचमार्क टाइमस्टैम्प बनाएंगे, preexec()फिर precmd()प्रॉम्प्ट का उपयोग करके कमांड को निष्पादित करने के समय की गणना करें और प्रॉम्प्ट से पहले इसे आउटपुट करें या इसे लॉग इन करें। उदाहरण:

preexec() {
   CMDSTART=$(date +%s%N)
}
precmd() {
   CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
   echo "Last command ran for $CMDRUNTIME nanoseconds."
}

नोट: इस विशेष उदाहरण के लिए, एक और भी आसान बिल्टइन फ़ंक्शन है। आपको बस इतना करना है कि ZSH में रनटाइम रिपोर्टिंग चालू करें और यह स्वचालित रूप से ऐसा करेगा।

$ export REPORTTIME=0
$ ls -d
./
ls -BF --color=auto -d  0.00s user 0.00s system 0% cpu 0.002 total

के अधिक व्यावहारिक कार्यान्वयन में preexec(), मैं इसका उपयोग करता हूं कि क्या शेल अंदर चल रहा है tmuxया नहीं screen, यदि हां, तो टैब नाम में प्रदर्शित होने के लिए वर्तमान में चल रहे कमांड अपस्ट्रीम के बारे में जानकारी भेजने के लिए।

दुर्भाग्य से इस छोटे से तंत्र में मौजूद नहीं है। यहाँ एक व्यक्ति को इसे दोहराने का प्रयास है । इसी तरह की निफ्टी छोटी हैक के लिए गिल्स का जवाब भी देखें ।




काश यह बाश में उपलब्ध होता!
वॉरेन

देखें गाइल्स के और दूसरों के लिंक, इसके लिए थोड़े अधिक नगण्य साथ बैश में कार्यान्वयन योग्य है। फिर, आप सिर्फ zsh क्यों नहीं चलाते? यह सिर्फ इस से स्विच करने के लिए और अधिक अच्छे कारणों के साथ एक रॉकिंग शेल है!
कालेब

2
यदि आप zsh का उपयोग कर रहे हैं तो इसे करने का एक और बेहतर तरीका है। जब सेट किया गया REPORTTIME पर्यावरण चर निष्पादन समय जानकारी (जैसे कि आपने इसके सामने कमांड को 'समय' के साथ चलाया था) को $ REPORTTIME सेकंड से अधिक समय तक ले जाएगा। बस इसे 0 पर सेट करें और यह आपको हर कमांड के लिए समय बताएगा, जिसमें उपयोगकर्ता / sys का ब्रेकडाउन बूट हो सकता है।
जोसेफ गार्विन

1

सबसे आसान तरीका शायद सेट करना होगा PROMPT_COMMANDबैश वेरिएबल्स देखें :

PROMPT_COMMAND
यदि सेट किया जाता है, तो मान को प्रत्येक प्राथमिक संकेत ( $PS1) के मुद्रण से पहले निष्पादित करने के लिए एक कमांड के रूप में व्याख्या की जाती है ।

उदाहरण के लिए, किसी भी मौजूदा प्रॉम्प्ट कमांड पर ओवरराइटिंग से बचने के लिए, आप कर सकते हैं:

PROMPT_COMMAND="date ; ${PROMPT_COMMAND}"

उस बारे में पता नहीं था - एक अच्छी शुरुआत की तरह दिखता है, @cjm
वॉरेन

1
यह एक शुरुआत है, लेकिन यह जानने की समस्या को संबोधित नहीं करता है कि कमांड कब चलाया गया था। कमांड टाइप होने और चलने से पहले प्रॉम्प्ट को मिनटों या घंटों या दिनों तक खींचा जा सकता है।
कालेब

0

csh/ tcshइस सुविधा के लिए सबसे अच्छा समर्थन है (और हमेशा यह किया है)।

  The `time` shell variable can be set to execute the time builtin  command
  after the completion of any process that takes more than a given number
  of CPU seconds.

दूसरे शब्दों में, set time=1किसी भी कमांड द्वारा उपभोग किए गए समय (सिस्टम, उपयोगकर्ता, बीता हुआ) को प्रिंट करेगा जो कि cpu समय के 1 सेकंड से अधिक समय लेता है। सादा set timeसभी आदेशों के लिए समय प्रिंट करने में सक्षम होगा।

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