मैं उत्पादन की अंतिम पंक्ति को कैसे चला सकता हूं?


12

मुझे पता है कि मैं आखिरी कमांड को बैश में !!चला सकता हूं, लेकिन मैं आउटपुट की आखिरी लाइन कैसे चला सकता हूं?

मैं इस आउटपुट के उपयोग के मामले में सोच रहा हूँ:

The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

लेकिन मुझे नहीं पता कि मैं इसे कैसे चला सकता हूं। मैं कुछ की तरह सोच रहा हूँ !!, शायद @@या इसी तरह?


सुपर यूजर के पास भी यह सवाल है।


1
आप इसे कॉपी और पेस्ट क्यों नहीं करते?
पायलट

1
@ समय आप किसी प्रोग्राम के आउटपुट की अंतिम पंक्ति को चलाने के तरीके चाहते हैं, लेकिन इस विशेष उपयोग के मामले में, command_not_found_handleशेल फ़ंक्शन या इसे चलाने वाली स्क्रिप्ट (आमतौर पर सिर्फ /usr/lib/command-not-found) को बदलने का भी तरीका है । मुझे लगता है कि आप इसे बना सकते हैं ताकि आप पैकेज को स्वचालित रूप से स्थापित करने के विकल्प के साथ अंतःक्रियात्मक रूप से प्रेरित हों, या (शायद बेहतर) ताकि पैकेज का नाम कहीं संग्रहीत हो और एक छोटी कमांड चलाकर स्थापित किया जा सके। जो आपने यहां पूछा है, उससे काफी अलग है, आप इसके बारे में एक अलग प्रश्न पोस्ट करने पर विचार कर सकते हैं।
एलिया कगन


2
यह भी प्रासंगिक हो सकता है: github.com/nvbn/thefuck (नाम को अनदेखा करें) यह उपकरण ऑटो git / apt / etc कमांड को सही करता है :)
bhathiya-perera

जवाबों:


16

कमांड $(!! |& tail -1)को करना चाहिए:

$ git something
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

$ $(!! |& tail -1)
$(git something |& tail -1)
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
git-man liberror-perl

जैसा कि आप देख सकते हैं कि sudo apt-get install gitकमांड चल रहा है।

EDIT: ब्रेकिंग डाउन$(!! |& tail -1)

  • $()है bashआदेश प्रतिस्थापन पैटर्न

  • bash!!अंतिम निष्पादित कमांड में विस्तारित होगा

  • |&हिस्सा मुश्किल है। आम तौर पर पाइप |बाएं तरफा कमांड के STDOUT को ले जाएगा और इसे STDIN के रूप में कमांड के दाईं ओर पारित करेगा |, आपके मामले में पिछली कमांड STDERR पर एक त्रुटि संदेश के रूप में अपना आउटपुट प्रिंट करता है। इसलिए, ऐसा करने से |मदद नहीं मिलेगी, हमें सही पक्षीय आदेश के लिए STDOUT और STDERR (या केवल STDERR) दोनों को पास करना होगा। |&STDOUT और STDERR दोनों को STDIN के रूप में दाएं तरफा कमांड में पास करेंगे। वैकल्पिक रूप से, बेहतर होगा कि आप केवल STDERR पास कर सकें:

    $(!! 2>&1 >/dev/null | tail -1)
  • tail -1हमेशा की तरह अपने इनपुट से अंतिम लाइन प्रिंट करेगा। यहां अंतिम पंक्ति को प्रिंट करने के बजाय आप अधिक सटीक हो सकते हैं जैसे उस लाइन को प्रिंट करना जिसमें apt-get installकमांड शामिल है :

    $(!! 2>&1 >/dev/null | grep 'apt-get install')

1
आपका दृष्टिकोण यह मान लेता है कि आउटपुट दूसरी बार के समान होगा। कुछ कमांड अगली बार के आसपास एक अलग आउटपुट का उत्पादन कर सकते हैं, इस मामले में यह भविष्यवाणी करना बहुत मुश्किल है कि इसके आउटपुट की अंतिम पंक्ति वास्तव में क्या करने जा रही है।
दोपहर

1
@kasperd आप सही कह रहे हैं। जहां तक ​​इस विशिष्ट उदाहरण का संबंध है, तो आउटपुट समान होना चाहिए ..
heemayl

7

टी एल; डॉ: alias @@='$($(fc -ln -1) |& tail -1)'

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

यह अंतिम कमांड को पुन: निर्देशित करने और stdout और stderr ( |&) दोनों को कमांड प्रतिस्थापन में पाइप करने के दृष्टिकोण को छोड़ देता है । heemayl का उत्तर इसे प्राप्त करता है, लेकिन इसका उपयोग अन्य उपनाम में नहीं किया जा सकता क्योंकि शेल उपनामों के विस्तार से पहले इतिहास का विस्तार करता है, और बाद में नहीं।

मुझे शेल फ़ंक्शन में काम करने के लिए इतिहास विस्तार नहीं मिल सकता है, यहां तक ​​कि इसे फ़ंक्शन में सक्षम करके भी set -H। मुझे संदेह है !!कि एक समारोह में कभी भी विस्तार नहीं किया जाएगा, और मुझे यकीन नहीं है कि अगर यह होता तो इसका विस्तार क्या होता, लेकिन अभी मुझे यकीन नहीं है कि यह ठीक क्यों है।

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

जैसा कि गॉर्डन डेविसन के बैश इतिहास विस्तार ( सुपर उपयोगकर्ता पर ) में एक उपनाम बनाने का जवाब है , अनुकरण करता है । के लिए इस में प्लग लगाने में heemayl के आदेश पैदावार:$(fc -ln -1)!!!! $(!! |& tail -1)

$($(fc -ln -1) |& tail -1)

यह काम करता है $(!! |& tail -1)लेकिन एक अन्य परिभाषा में जा सकता है:

alias @@='$($(fc -ln -1) |& tail -1)'

आपको लगता है कि परिभाषा चलाते हैं, या में रख के बाद .bash_aliasesया .bashrcऔर एक नया खोल शुरू करते हैं, तो आप बस टाइप कर सकते हैं @@पिछले आदेश से आउटपुट की अंतिम पंक्ति पर अमल करने का प्रयास करने (या जो भी आप उर्फ नाम)।

ek@Io:~$ alias @@='$($(fc -ln -1) |& tail -1)'
ek@Io:~$ evolution
The program 'evolution' is currently not installed. You can install it by typing:
sudo apt-get install evolution
ek@Io:~$ @@
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  evolution-common evolution-data-server evolution-data-server-online-accounts
....

क्या इसे अलग स्क्रिप्ट में स्थानांतरित करने का कोई विकल्प है? मैंने कोशिश की कि आखिरकार असफल हो गया, क्योंकि fc कुछ नहीं करता है ... जैसा कि fc वर्तमान शेल सत्र के इतिहास का अनुसरण करता है, इसलिए इसे एक अलग स्क्रिप्ट में ले जाने से खाली इतिहास के साथ एक अलग सत्र खुल जाता है, निश्चित रूप से ... मैंने कुछ जोड़ा स्क्रिप्ट में fc लाइन के ऊपर कमांड, और उनमें से एक को निष्पादित किया गया था। इसलिए, मुझे आश्चर्य है कि क्या स्क्रिप्ट को बताने का कोई विकल्प है, कि इसका "संदर्भ" बैश सत्र है, जिसने इसे निष्पादित किया। जैसे, #! / बिन / बैश या कुछ के लिए कुछ तर्क ...
Exterminator13

@ Exterminator13 यदि आप एक अलग स्क्रिप्ट का मतलब है कि आप चलाते हैं - जैसे ./script, यह नहीं कि आप स्रोत .या बिलिन के साथ स्रोत source- मैं अनिश्चित हूँ। बैश खोल से बाहर निकलने पर एक फाइल करने के लिए संलग्न कर देता है या जब आप चलाने के historyसाथ -aया -w(देखें help history)। यदि ऐसा किया जाता है, तो कई इंटरेक्टिव गोले में कमांड को इंटरलीव किया जाएगा (उस क्रम में दिखाई दे रहा है जो आपने उन्हें चलाया था)। आप इसे तुरंत बना सकते हैं। । लेकिन मुझे लगता है कि fcस्क्रिप्ट में काम करने के लिए बहुत कुछ है। मैं इस बारे में एक नया प्रश्न पोस्ट करने का सुझाव देता हूं। यदि आप ऐसा करते हैं, तो कृपया इसके लिंक के साथ यहां टिप्पणी करने के लिए स्वतंत्र महसूस करें।
एलियाह कगन

2

यदि आप X के तहत टर्मिनल एमुलेटर का उपयोग कर रहे हैं, जैसे gnome-terminal, konsoleया xterm, आप कॉपी और पेस्ट जैसी किसी चीज के लिए एक्स चयन का उपयोग कर सकते हैं:

प्राथमिक चयन का उपयोग करें

ट्रिपल बाईं क्लिक के साथ चलने के लिए पूरी लाइन का चयन करें

फिर मध्य बटन क्लिक का उपयोग करके इसे कमांड लाइन पर पेस्ट करें

यह ज्यादातर टर्मिनल एमुलेटर में काम करना चाहिए। यह प्राथमिक चयन का उपयोग करता है, क्लिपबोर्ड को छूने के बिना - वे अलग हैं।
यह तकनीकी रूप से एक ऑपरेशन में, और फिर संयुक्त प्रतिलिपि और पेस्ट का चयन कर रहा है।


1
@ यह सच है - मैं यह स्पष्ट कर दूँगा।
वोल्कर सेगल

1

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

निम्नलिखित पंक्तियाँ आप में डालें ~/.screenrc:

register t "^a[k0y$ ^a]^a^L"
bind t process t

फिर आप वर्तमान प्रॉम्प्ट में पिछली पंक्ति सम्मिलित करने के लिए Ctrl+ दबा सकते हैं at। यह संभव है कि यह भी स्वतः ही एंटर दबाए, लेकिन इसे चलाने से पहले इसे जांचना बेहतर होगा और बस मैन्युअल रूप से एंटर दबाएं।

यह काम किस प्रकार करता है:

  • register tनाम के एक बफर में एक स्ट्रिंग पंजीकृत करता है t। निम्नलिखित स्ट्रिंग एक महत्वपूर्ण अनुक्रम है।
  • bind tकुंजी से बांधता है t(यानी Ctrl+ का उपयोग करके निष्पादित करता है at), process tजिसका अर्थ है नामित बफर की सामग्री का मूल्यांकन करना t
  • अनुक्रम का अर्थ है:
    • ^a[(= Ctrla[): कॉपी मोड दर्ज करें
    • kएक पंक्ति ऊपर जाएं, पंक्ति 0की शुरुआत में जाएं, पंक्ति के y$अंत तक कॉपी करें, (स्थान) कमांड को पूरा करें
    • ^a](= Ctrla]): कॉपी की गई सामग्री पेस्ट करें
    • ^a^L(= CtrlaCtrlL) स्क्रीन को रिफ्रेश करें (अन्यथा पेस्ट की गई सामग्री दिखाई नहीं देगी, क्योंकि आपने इसे स्वयं टाइप नहीं किया था
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.