PS1 शीघ्र समय दिखाने के लिए


10

मैं वर्तमान में अपने बैश प्रॉम्प्ट में वर्तमान समय प्रदर्शित करने के लिए इसका उपयोग करता हूं:

PS1=\[\e[0;32m\]\t \W>\[\e[1;37m\]

20:42:23 ~>

क्या पिछले संकेत के बाद बीता हुआ समय प्रदर्शित करना संभव है? जैसे कि:

00:00:00 ~> sleep 10
00:00:10 ~> sleep 20
00:00:20 ~>

यह आम तौर पर पृष्ठभूमि में एक स्क्रिप्ट द्वारा PS1 को समय-समय पर बदलना संभव नहीं है?



नहीं, उस पोस्ट का कोई जवाब नहीं है और मैं उम्मीद करता हूं कि जब कोई नया प्रॉम्प्ट प्रदर्शित हो, तो केवल उसे बदलने के लिए संकेत दें।
TeasingDart

वास्तव में आप क्या पूछते हैं करने के लिए एक संभव तरीका नहीं है, नहीं।
डोपघोटी

1
यदि प्रदर्शन मूल्य स्थिर है तो यह संभव है (ओपी का प्रश्न यह अनुमति देने के लिए प्रकट नहीं हुआ)। शेल चर में पिछली बार के युग को बचाकर बीता हुआ समय बनाए रखा जा सकता है। इसे लागू करना बहुत काम लगता है, हालांकि (एक या एक घंटे - शायद कोई व्यक्ति जो मेरे मन में है, उससे अधिक सरल समाधान प्रदान करेगा)। यह सवाल मददगार होगा।
थॉमस डिके

जवाबों:


10

इसे करने का एक तरीका PS1 को संशोधित करने वाले कोड को निष्पादित करने के लिए bash के PROMPT_COMMAND फीचर का उपयोग करना होगा। नीचे दिया गया फ़ंक्शन मेरे मूल सबमिशन का एक अद्यतन संस्करण है; यह एक दो कम पर्यावरण चर का उपयोग करता है और "_PS1_" के साथ उन्हें उपसर्ग करता है ताकि मौजूदा चर की क्लोबिंग से बचने की कोशिश की जा सके।

prompt_command() {
  _PS1_now=$(date +%s)
  PS1=$( printf "\[\e[0;32m\]%02d:%02d:%02d \W>\[\e[1;37m\] " \
           $((  ( _PS1_now - _PS1_lastcmd ) / 3600))         \
           $(( (( _PS1_now - _PS1_lastcmd ) % 3600) / 60 )) \
           $((  ( _PS1_now - _PS1_lastcmd ) % 60))           \
       )
  _PS1_lastcmd=$_PS1_now
}
PROMPT_COMMAND='prompt_command'
_PS1_lastcmd=$(date +%s)

चीजों को शुरू करने के लिए अपने .bash_profile में रखें।

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

00:00:02 ~> sleep 5   ## here I typed really quickly
00:00:05 ~> sleep 3   ## here I took about 2 seconds to enter the command
00:00:10 ~> sleep 30 ## more slow typing
00:01:35 ~>

देर से जोड़:

@Cyrus के अब हटाए गए उत्तर के आधार पर, यहां एक संस्करण है जो अतिरिक्त चर के साथ पर्यावरण को अव्यवस्थित नहीं करता है:

PROMPT_COMMAND='
    _prompt(){
        PROMPT_COMMAND="${PROMPT_COMMAND%-*}-$SECONDS))\""
        printf -v PS1 "\[\e[0;32m\]%02d:%02d:%02d \W>\[\e[1;37m\] " \
                      "$(($1/3600))" "$((($1%3600)/60))" "$(($1%60))"
    }; _prompt "$((SECONDS'"-$SECONDS))\""

अतिरिक्त देर से जोड़:

संस्करण 4.2 ( echo $BASH_VERSION) में शुरू करके , आप dateएक नए प्रिंटफ प्रारूप स्ट्रिंग के साथ बाहरी कॉल से बच सकते हैं ; $(date +%s)टुकड़ों को बदल दें $(printf '%(%s)T' -1)संस्करण 4.3 में शुरू , आप -1" अब कोई तर्क नहीं है " व्यवहार पर भरोसा करने के लिए पैरामीटर को छोड़ सकते हैं ।


यह असली करीब है। यह तब काम करता है जब मैं बैश प्रॉम्प्ट से कॉपी / पेस्ट करता हूं, लेकिन जब मैंने इसे अपने .bashrc में जोड़ने की कोशिश की, तो यह "1451424431 प्रिंट करता है: कमांड नहीं मिली"
TeasingDart

शायद थोड़ा बहुत नकल / चिपकाया गया?
जेफ स्कालर

इस अंतिम संस्करण ने काम किया, जो मैं चाहता था! मुझे लगता है कि प्रॉम्प्ट के बाद टेक्स्ट का रंग सेट करने के लिए मेरे जाल के साथ कुछ करना था। धन्यवाद।
TeasingDart

जब आप $SECONDSइसे रीसेट करते हैं, तो शेल शुरू होने के समय को ट्रैक करना बंद कर देता है,
mikeserv

1
@chepner - ठीक है, निश्चित है, लेकिन यह शेल के समय को फिर से नहीं रखता है। मुझे गलत मत समझो - मैंने इसे गलत ठहराया क्योंकि यह एक अच्छा जवाब है - लेकिन मुझे लगता है कि $SECONDSहर संकेत के लिए एक इंटरैक्टिव शेल को पुनर्परिभाषित करने से अप्रत्याशित व्यवहार की संभावना है। रन-टाइम के मूल्यांकन से जुड़े किसी भी कारण से इसका उपयोग करने वाला कोई अन्य शेल फ़ंक्शन दुर्व्यवहार करेगा।
दोपहर

4
PS1[3]=$SECONDS
PS1='${PS1[!(PS1[1]=!1&(PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600))
   ]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]/60%60),  ${PS1[3]})):${PS1[1
   ]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]%60),     ${PS1[3]})):${PS1[1
   ]#${PS1[3]%%*??}0}$((PS1[3]=(SECONDS),       ${PS1[3]})):'$PS1

यह गणना द्वारा प्रारूपण को संभालता है - इसलिए, जबकि यह कई बार विस्तार करता है, यह कोई उपधारा या पाइप नहीं करता है।

यह सिर्फ $PS1एक सरणी के रूप में व्यवहार करता है और संकेतों के बीच किसी भी / सभी आवश्यक स्थिति को स्टोर / गणना करने के लिए उच्च सूचकांकों का उपयोग करता है। कोई अन्य शेल राज्य प्रभावित नहीं होता है।

00:00:46:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:00:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:43:[mikeserv@desktop tmp]$ sleep 10
00:00:33:[mikeserv@desktop tmp]$ sleep 10
00:00:15:[mikeserv@desktop tmp]$
00:00:15:[mikeserv@desktop tmp]$
00:00:02:[mikeserv@desktop tmp]$
00:02:27:[mikeserv@desktop tmp]$

मैं इसे थोड़ा नीचे तोड़ सकता हूँ ...

सबसे पहले, वर्तमान मूल्य को सहेजें $SECONDS:

PS1[3]=$SECONDS

इसके बाद, $PS1[0]इस तरह से आत्म-पुनरावृत्ति को परिभाषित करें जो हमेशा $PS1[1-3]एक साथ आत्म-संदर्भित करते समय सही मान सेट करेगा । इस भाग को प्राप्त करने के लिए आपको उस क्रम पर विचार करना होगा जिसमें शेल-गणित के भावों का मूल्यांकन किया जाता है। सबसे महत्वपूर्ण बात, शेल-गणित हमेशा शेल-गणित के लिए व्यापार का अंतिम क्रम है। अन्य सभी से पहले, शेल मूल्यों का विस्तार करता है। इस तरह से आप उपयोग करके इसे असाइन करने के बाद एक गणित अभिव्यक्ति में शेल-चर के लिए एक पुराने-मूल्य का संदर्भ दे सकते हैं $

यहाँ पहले एक सरल उदाहरण दिया गया है:

x=10; echo "$(((x+=5)+$x+x))" "$x"

40 15

शेल उस कथन का मूल्यांकन करेगा $xजहां पहले $डॉलर-चिह्न संदर्भ का उपयोग किया जाता है, और फिर अभिव्यक्ति बन जाती है।

(x+=5)+10+x

... तो शेल 5 के मान को जोड़ता है $xऔर बाद में संपूर्ण अभिव्यक्ति का विस्तार करता है x+10+x, जबकि केवल संदर्भ चर में वास्तव में असाइन किए गए मान को बनाए रखता है। और इसलिए गणित की अभिव्यक्ति का विस्तारित मूल्य 40 है, लेकिन अंतिम मूल्य $x15 है।

यह काफी हद तक है कि $PS1समीकरण कैसे काम करता है, सिवाय इसके कि सरणी सूचकांकों में आगे चलकर गणित के विस्तार / मूल्यांकन का एक और स्तर है।

PS1='${PS1[!(PS1[1]=!1&(...))]#...}...'

मुझे वास्तव में यकीन नहीं है कि मैंने PS1[1]=!1वहां क्यों चुना - मुझे लगता है कि यह शायद मूर्खतापूर्ण सौंदर्यशास्त्र था - लेकिन यह $PS1[1]पैरामीटर प्रतिस्थापन के लिए इसे विस्तारित करते हुए 0 प्रदान करता है । एक बिटवाइज़ का मान और 0 के लिए और कुछ भी हमेशा 0 होगा, लेकिन यह शॉर्ट-सर्किट नहीं करता है क्योंकि बूलियन &&तब करता है जब लेफ्ट-मोस्ट प्राइमरी 0 होता है और इसलिए पैरेंटिकल एक्सप्रेशन का मूल्यांकन हर बार हो जाता है। यह महत्वपूर्ण है, निश्चित रूप से, क्योंकि यह पहला एलिप्सीस है जहां प्रारंभिक मान $PS1[2,3]निर्धारित किए गए हैं।

वैसे भी, $PS1[1]यहाँ 0 होने का आश्वासन दिया गया है, भले ही छेड़छाड़ w / शीघ्र ड्रॉ के बीच हो। कोष्ठक के भीतर ...

PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600

... $PS1[2]के अंतर असाइन किया गया है $PS1[3]और $SECONDS, और $PS1[3]है कि मूल्य और 3600 के सभी मान यहाँ प्रारंभ कर रहे हैं के भागफल असाइन किया गया है। इसलिए:

${PS1[1]#${PS1[3]%%*??}0}

... यदि कम से कम दो अंक हैं $PS1[3]तो आंतरिक विस्तार शून्य है, और क्योंकि हम जानते हैं $PS1[1]कि 0 है तो अगर $PS1[3]कुछ भी नहीं करने के लिए दूर प्रतिस्थापित किया जा सकता है, तो यह भी $PS1[1]इसके मूल्य में विस्तार किया गया है। इस तरह से $PS1[3]असाइनमेंट के प्रत्येक पुनरावृत्ति के लिए केवल एक अंक का मान एक अग्रणी शून्य का विस्तार करेगा, और $PS1[3]उसके बाद तुरंत ही modulo 60 का विस्तार किया जाता है , जबकि समवर्ती रूप से प्रत्येक घंटे, मिनट, सेकंड के लिए अगले क्रमिक छोटे मान को असाइन किया जाता है।

कुल्ला और फिर से दोहराएं, जब तक कि अंतिम पुनरावृत्ति जब $PS1[3]डब्ल्यू को अधिलेखित नहीं किया जाता है / तो वर्तमान मूल्य $SECONDSताकि इसकी तुलना $SECONDSएक बार फिर से की जा सके जब संकेत अगले खींचा जाता है।


1

अब तक मुझे मिला सबसे अच्छा समाधान यह है: https://github.com/jichu4n/bash-command-timer

जो [ 1s011 | May 25 15:33:44 BST ]निष्पादित कमांड के बाद दाहिने हाथ की तरफ उर्फ ​​समय को प्रिंट करता है, इसलिए यह आपको PS1 को अव्यवस्थित नहीं करता है।

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

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