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 है, लेकिन अंतिम मूल्य $x
15 है।
यह काफी हद तक है कि $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
एक बार फिर से की जा सके जब संकेत अगले खींचा जाता है।