क्या zsh पिछले रन प्रोग्राम के स्टैडआउट तक पहुंच सकता है?


16

मैं अक्सर उपयोग findया locateरास्तों के बारे में पता लगाने के लिए।

(~) locate foobar.mmpz
/home/progo/lmms/projects/foobar.mmpz

अगला चरण अक्सर फ़ाइलों को खोलने या अन्यथा हेरफेर करने के लिए होता है। ऊपर जैसे खुशहाल मामले में, मैं यह कर सकता हूं:

(~) ls `!!`
ls `locate foobar.mmpz`
/home/progo/lmms/projects/foobar.mmpz

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

वहाँ बाद में हेरफेर के लिए एक सरणी में stdout स्टोर करने के लिए zsh को हुक करने का एक तरीका होगा? आखिरकार, यह उपयोगकर्ता के लिए स्ट्रीम को पुनर्निर्देशित करने के लिए शेल का काम है। मुझे लगता है कि यह पहले और अंतिम N लाइनों को एक चर में तत्काल बाद के उपयोग, जैसे $?और अन्य के लिए संग्रहीत कर सकता है।

ठीक है तो यह बहुत अच्छा है: /unix//a/59704/5674 । अब मैं प्रत्येक रन लाइन के बाद इस तरह के कैप्चर को रिग करने के लिए zsh के बारे में जानता हूं (और कोड को zsh में पोर्ट कर रहा हूं)।


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

@StephaneChazelas, लेकिन यह शेल का काम है, कहना, प्रति उपयोगकर्ता के अनुरोधों पर फाइलों में पुनर्निर्देशित करना। Zsh के लिए ऐसी रेसिपी भी हैं जो लाल रंग को अलग करती हैं और इसे स्टडआउट से अलग करती हैं। मुझे लगता है कि स्ट्रीमिंग मामलों में शेल की भूमिका इंगित करती है।
nperson325681

हां, आप इसका उपयोग कर सकते हैं screenया scriptप्रेडम और प्रीक्सेक हुक का उपयोग कर सकते हैं ।
स्टीफन चेज़लस

जवाबों:


7

अधिकांश टर्मिनल एमुलेटर पर स्क्रीन से आउटपुट कैप्चर करने की कोई सुविधा नहीं है। मुझे लगता है कि xterm ("संदर्भ" टर्मिनल एमुलेटर) के लेखक को याद करते हुए कहते हैं कि इसे लागू करना मुश्किल होगा। यहां तक ​​कि अगर यह संभव था, तो शेल को उस स्थान का ट्रैक रखना होगा जहां अंतिम संकेत दिया गया था।

जब तक आप टर्मिनल-विशिष्ट, मैनुअल तंत्र का उपयोग नहीं करते हैं, तब तक आप xterm में माउस के साथ कॉपी-पेस्टिंग या स्क्रीन में कीबोर्ड के साथ उपयोग नहीं कर सकते।

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

आप कमांड को फिर से चलाएँ और इसके आउटपुट को कैप्चर कर सकते हैं। प्रत्येक को करने के विभिन्न तरीके हैं। कमांड को पुन: चलाने के लिए, आप उपयोग कर सकते हैं:

  • !! इतिहास प्रतिस्थापन - टाइप करने के लिए सबसे सुविधाजनक;
  • fc -e -, जिसका उपयोग किसी फ़ंक्शन में किया जा सकता है।

आउटपुट कैप्चर करने के लिए, आप कमांड प्रतिस्थापन या निम्न की तरह एक फ़ंक्शन का उपयोग कर सकते हैं:

K () {
  lines=("${(f@)$(cat)}")
}
!! |K

यह linesसरणी को उस कमांड के आउटपुट में सेट करता है जो उसमें पाइप किया गया है।


ऐसा ही होगा। मुझे अब अच्छी व्याख्याओं के मद्देनजर पता चलता है कि पूरी तरह से स्वचालित दृष्टिकोण बहुत मुश्किल है, दूसरी सबसे अच्छी बात यह है कि यह Kआपकी तरह है ।
nperson325681

3

यहाँ एक चर नामक आउटपुट की अंतिम पंक्ति डालने के लिए किसी चीज़ का पहला कट है $lastline

precmd () {                                                                                                                                                                                                        
    exec 2>&- >&-
    lastline=$(tail -1 ~/.command.out) 
    sleep 0.1   # TODO: synchronize better
    exec > /dev/tty 2>&1
}

preexec() {
    exec > >(tee ~/.command.out&)
}

यह कमांड के स्टडआउट की एक कॉपी को स्टोर करने के preexecलिए चलाने execके teeलिए zsh के हुक का उपयोग करता है, फिर precmdस्टोर किए गए आउटपुट को पढ़ने के लिए और प्रॉम्प्ट को दिखाने के लिए केवल टर्मिनल होने के लिए stdout को पुनर्स्थापित करने के लिए उपयोग करता है।

लेकिन इसके लिए अभी भी कुछ काम करने की जरूरत है। उदाहरण के लिए, चूंकि stdout अब एक टर्मिनल नहीं है, इसलिए जैसे कार्यक्रम vimऔर lessठीक से काम नहीं करते हैं।

इन सवालों में कुछ उपयोगी संबंधित जानकारी है:


हां, शायद 100% स्वचालित दृष्टिकोण काम नहीं कर रहा है। execकोड में कई कॉल हैं , क्या कमांड कई बार चल रही है या क्या मैं विशेष शब्दार्थ में पकड़ा गया हूं?
nperson325681

execएक कार्यक्रम के नाम के बिना सिर्फ पुनर्निर्देशन निर्धारित करता है।
मिकेल

2

आप अपने परिणामों को केवल पाइप करके ऐसा कर सकते हैं tee, जो आउटपुट को केवल एक फ़ाइल में सहेजता है और उसी समय प्रदर्शित करता है।

उदाहरण के लिए, आप ऐसा कर सकते हैं, जो आपके आउटपुट को सामान्य की तरह दिखाता है, लेकिन इसे फ़ाइल में भी सेव करता है /tmp/it

locate foobar.mmpz | tee /tmp/it

फिर उस फ़ाइल को कैट करें और चीजों का चयन करने के लिए इसे grep करें, जैसे

cat /tmp/it | grep progo | grep lms

फिर इसका उपयोग करने के लिए, आप बस ऐसा कर सकते हैं:

vi $(!!)


2

मैं इस आधे बेक्ड समाधान के साथ आया:

alias -g ___='"$(eval "$(fc -ln -1)" | tail -n 1)"'

यह आपको ___कमांड लाइन में किसी भी बिंदु पर लिखने की अनुमति देता है । पिछली कमांड को फिर से चलाया ___जाएगा और इसे अपने आउटपुट की अंतिम पंक्ति से बदल दिया जाएगा। उदाहरण का उपयोग:

$ touch foo bar baz
$ ls -1
bar
baz
foo
$ vim ___

अंतिम आदेश का विस्तार किया जाएगा vim foo

यह कुछ तेज किनारों है!

  • यदि आप ___एक कमांड में शामिल हैं , लेकिन पिछली कमांड में ए भी शामिल है ___, तो शेल कुछ समय के लिए अजीब स्थिति में लटका रहेगा। आप के साथ तुरंत इस राज्य से बाहर निकल सकते Ctrl- C

  • आप इसके साथ और अन्य निर्माणों के Tabविस्तार के लिए भी प्रेस नहीं ___कर सकते !$

  • जब वे "सामान्य रूप से" चलाए जाते हैं और जब वे एक पाइप से जुड़े होते हैं, तो कुछ कमांड अलग-अलग आउटपुट प्रदर्शित करेंगे। (के उत्पादन की तुलना करें lsऔर ls | cat।) यदि आदेश से शुरू हो रहा ___है इन में से एक है, आप एक अलग आदेश आपकी अपेक्षा से चल रहा है खत्म हो सकता है।

  • और हां, अगर आप पिछले एक के अलावा किसी आउटपुट लाइन के साथ कुछ करना चाहते हैं, तो यह आपकी मदद नहीं करेगा।

मैंने नाम उठाया ___क्योंकि यह ऐसा कुछ है जिसे मैंने कमांड लाइन में एक शब्द के रूप में शामिल करना कभी नहीं चाहा, तर्क के रूप में भी नहीं। आप एक अलग नाम चुन सकते हैं, लेकिन इस बात का ध्यान रखें कि अनजाने में आपके लिए कुछ ऐसी चीज का चयन न किया जाए जो आपके लिए विस्तारित हो।

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