बैश का उपयोग करके एक चर में अंतिम कमांड के आउटपुट को स्वचालित रूप से कैप्चर करें?


139

मैं एक अंतिम आदेश में अंतिम निष्पादित कमांड के परिणाम का उपयोग करने में सक्षम होना चाहता हूं। उदाहरण के लिए,

$ find . -name foo.txt
./home/user/some/directory/foo.txt

अब हम कहते हैं कि मैं एक संपादक में फ़ाइल खोलने में सक्षम होना चाहता हूं, या इसे हटा देना चाहता हूं, या इसके साथ कुछ और करना चाहता हूं, जैसे

mv <some-variable-that-contains-the-result> /some/new/location

मैं यह कैसे कर सकता हूं? शायद कुछ बैश चर का उपयोग कर?

अपडेट करें:

स्पष्ट करने के लिए, मैं चीजों को मैन्युअल रूप से असाइन नहीं करना चाहता। इसके बाद मैं बिल्ट-इन वैर वैरिएबल की तरह कुछ हूं

ls /tmp
cd $_

$_पिछले कमांड का अंतिम तर्क रखता है। मैं कुछ ऐसा ही चाहता हूं, लेकिन अंतिम कमांड के आउटपुट के साथ।

अंतिम अद्यतन:

सेठ के जवाब ने काफी अच्छा काम किया है। कुछ बातों का ध्यान रखें:

  • touch /tmp/xबहुत पहली बार समाधान की कोशिश करते समय मत भूलना
  • अंतिम कमांड का निकास कोड सफल होने पर परिणाम केवल संग्रहीत किया जाएगा

आपका संपादन देखने के बाद मैंने सोचा कि मैं अपना उत्तर हटा दूं। मुझे आश्चर्य है कि वहाँ कुछ भी बनाया गया है जिसमें आप देख रहे हैं।
टास्किनर 20

मुझे कुछ भी निर्मित नहीं मिला। मैं सोच रहा था कि क्या इसे लागू करना संभव होगा .. शायद .bahsrc के माध्यम से? मुझे लगता है कि यह एक बहुत आसान सुविधा होगी।
आर्मंडिनो

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

3
आप शेल और टर्मिनल के सहयोग के बिना ऐसा नहीं कर सकते हैं, और वे आम तौर पर सहयोग नहीं करते हैं। यह भी देखें कि मैं कमांड लाइन से अंतिम आउटपुट का पुन: उपयोग कैसे करूं? और यूनिक्स स्टैक एक्सचेंज पर पिछले कमांड के आउटपुट से टेक्स्ट का उपयोग करना
गिल्स एसओ- बुराई को रोकें '23

6
कमांड के आउटपुट को कैप्चर नहीं किए जाने का एक मुख्य कारण यह है कि आउटपुट मनमाने ढंग से बड़े हो सकते हैं - एक समय में कई मेगाबाइट। दी, हमेशा कि बड़े, लेकिन बड़े आउटपुट समस्याओं का कारण नहीं बनते।
जोनाथन लेफ़लर 4

जवाबों:


71

यह वास्तव में हैकी समाधान है, लेकिन ऐसा लगता है कि ज्यादातर समय कुछ काम करते हैं। परीक्षण के दौरान, मैंने नोट किया ^Cकि कमांड लाइन पर होने पर यह कभी-कभी बहुत अच्छा काम नहीं करता है , हालांकि मैंने इसे थोड़ा बेहतर व्यवहार करने के लिए इसे थोड़ा बदल दिया।

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


कहा जा रहा है, यहाँ "समाधान" है:

PROMPT_COMMAND='LAST="`cat /tmp/x`"; exec >/dev/tty; exec > >(tee /tmp/x)'

इस बैश पर्यावरण चर को सेट करें और कमांड को वांछित के रूप में जारी करें। $LASTआम तौर पर आपके द्वारा खोजे जा रहे आउटपुट होंगे:

startide seth> fortune
Courtship to marriage, as a very witty prologue to a very dull play.
                -- William Congreve
startide seth> echo "$LAST"
Courtship to marriage, as a very witty prologue to a very dull play.
                -- William Congreve

1
@armandino: यह निश्चित रूप से ऐसे कार्यक्रमों का कारण बनता है, जो मानक के आधार पर एक टर्मिनल के साथ बातचीत करने की उम्मीद करते हैं (उम्मीद से अधिक / कम) या $ LAST (emacs) में विषम चीजों को स्टोर करने के लिए नहीं। लेकिन मुझे लगता है कि यह उतना ही अच्छा है जितना आप पाने जा रहे हैं। केवल अन्य विकल्प का उपयोग (प्रकार) स्क्रिप्ट को किसी फ़ाइल की प्रतिलिपि बनाने के लिए बचाने के लिए किया जाता है और फिर PROMPT_COMMAND का उपयोग करके पिछले PROMPT_COMMAND के परिवर्तनों की जाँच के लिए। इसमें वह सामान शामिल होगा जो आप नहीं चाहते, हालांकि। मुझे पूरा यकीन है कि आप इस बारे में कुछ भी नहीं जानना चाहेंगे कि आप यह क्या चाहते हैं।
सेठ रॉबर्टसन

2
थोड़ा और आगे जाने के लिए: PROMPT_COMMAND='last="$(cat /tmp/last)";lasterr="$(cat /tmp/lasterr)"; exec >/dev/tty; exec > >(tee /tmp/last); exec 2>/dev/tty; exec 2> >(tee /tmp/lasterr)'जो दोनों प्रदान करता है $lastऔर $lasterr
16एफ़िंक

@ LCDosborn: डिफ़ॉल्ट रूप से आदमी एक पेजर के माध्यम से आउटपुट भेजता है। जैसा कि मेरी पिछली टिप्पणी में कहा गया था: "उम्मीद (अधिक / कम)" के रूप में काम नहीं करने के लिए मानक-आउट पर एक टर्मिनल के साथ बातचीत करने की उम्मीद करने वाले कार्यक्रम। अधिक और कम पेजर हैं।
सेठ रॉबर्टसन

मुझे मिलता है:No such file or directory
फ्रांसिस्को कॉर्लेस मोरेल्स

@ टिप्पणी मैं केवल एक सुधार बताना चाहता था: आपका सुझाव समाप्त होना चाहिए 2> >(tee /tmp/lasterr 1>&2)क्योंकि मानक आउटपुट teeको मानक त्रुटि पर वापस भेज दिया जाना चाहिए।
ह्यूजेज

90

मैं किसी भी चर का पता नहीं है जो यह स्वचालित रूप से करता है । परिणाम को कॉपी-पेस्ट करने से एक तरफ कुछ करने के लिए, आप जो कुछ भी करते हैं उसे फिर से चला सकते हैं, जैसे

vim $(!!)

जहाँ !!इतिहास विस्तार का अर्थ है 'पिछली आज्ञा'।

यदि आपको लगता है कि रिक्त स्थान या अन्य वर्णों के साथ एक एकल फ़ाइल नाम हो सकता है जो उचित तर्क पार्सिंग को रोक सकता है, तो परिणाम को उद्धृत करें ( vim "$(!!)")। इसे अधूरा छोड़ने से कई फाइलें एक ही बार में खोली जा सकेंगी, जब तक कि वे रिक्त स्थान या अन्य शेल पार्सिंग टोकन को शामिल नहीं करती हैं।


1
कॉपी-पेस्टिंग वह है जो मैं आमतौर पर ऐसे मामले में करता हूं, यह भी क्योंकि आपको आम तौर पर कमांड के आउटपुट का केवल एक हिस्सा चाहिए होता है। मुझे आश्चर्य है कि आप इसका उल्लेख करने वाले पहले व्यक्ति हैं।
ब्रूनो डी फेन

4
आप कम कीस्ट्रोक्स के साथ बहुत कुछ कर सकते हैं:vim `!!`
20

स्वीकृत उत्तर से अंतर देखने के लिए, निष्पादित करें date "+%N"और फिरecho $(!!)
Mar36

20

बैश एक बदसूरत भाषा की तरह है। हां, आप आउटपुट को वेरिएबल में असाइन कर सकते हैं

MY_VAR="$(find -name foo.txt)"
echo "$MY_VAR"

लेकिन बेहतर उम्मीद है कि आपकी सबसे मुश्किल यह है कि findकेवल एक परिणाम लौटा और उस परिणाम में कोई भी "अजीब" वर्ण नहीं था, जैसे गाड़ी रिटर्न या लाइन फीड, क्योंकि वे बैश चर में सौंपे जाने पर चुपचाप संशोधित हो जाएंगे।

लेकिन इसका उपयोग करते समय अपने चर को सही ढंग से उद्धृत करने के लिए बेहतर होगा!

यह सीधे फ़ाइल पर कार्य करने के लिए, के साथ जैसे बेहतर है findकी -execdir(परामर्श मैनुअल)।

find -name foo.txt -execdir vim '{}' ';'

या

find -name foo.txt -execdir rename 's/\.txt$/.xml/' '{}' ';'

5
जब आप असाइन करते हैं, तो वे चुपचाप संशोधित नहीं होते हैं, जब आप गूंजते हैं तो वे संशोधित होते हैं ! आपको केवल echo "${MY_VAR}"यह देखना है कि यह मामला क्या है।
paxdiablo

13

ऐसा करने के एक से अधिक तरीके हैं। एक तरीका यह है v=$(command)कि कमांड के आउटपुट को कौन सा उपयोग करेगा v। उदाहरण के लिए:

v=$(date)
echo $v

और आप backquotes का भी उपयोग कर सकते हैं।

v=`date`
echo $v

से बैश शुरुआती गाइड ,

जब प्रतिस्थापन के पुराने-शैली बैकक्लेटेड फॉर्म का उपयोग किया जाता है, तो बैकस्लैश "$", "` ", या" \ "का पालन करने के अलावा अपने शाब्दिक अर्थ को बरकरार रखता है। बैकस्लैश से पहले नहीं आने वाले पहले बैकटिक्स को कमांड प्रतिस्थापन कहते हैं। "$ (COMMAND)" फॉर्म का उपयोग करते समय, कोष्ठक के बीच के सभी अक्षर कमांड बनाते हैं; किसी के साथ भी विशेष व्यवहार नहीं किया जाता है।

संपादित करें: प्रश्न में संपादित होने के बाद, ऐसा लगता है कि यह वह चीज नहीं है जिसे ओपी देख रहा है। जहाँ तक मुझे पता है, $_अंतिम कमांड के आउटपुट के लिए कोई विशेष चर नहीं है ।


11

यह काफी आसान है। बैक-कोट्स का उपयोग करें:

var=`find . -name foo.txt`

और फिर आप भविष्य में किसी भी समय उपयोग कर सकते हैं

echo $var
mv $var /somewhere

11

Disclamers:

  • यह उत्तर देर से आधा वर्ष है: डी
  • मैं एक भारी tmux उपयोगकर्ता हूँ
  • आपको काम करने के लिए अपने शेल को tmux में चलाना होगा

जब tmux में एक इंटरैक्टिव शेल चल रहा है, तो आप आसानी से एक टर्मिनल पर वर्तमान में प्रदर्शित डेटा तक पहुंच सकते हैं। आइए कुछ दिलचस्प आदेशों पर एक नज़र डालें:

  • tmux कैप्चर-पेन : यह एक प्रदर्शित डेटा को tmux के आंतरिक बफ़र्स में से एक में कॉपी करता है। यह उस इतिहास को कॉपी कर सकता है जो वर्तमान में दिखाई नहीं दे रहा है, लेकिन अब हम इसमें रुचि नहीं ले रहे हैं
  • tmux list-buffers : यह कैप्चर किए गए बफ़र्स के बारे में जानकारी प्रदर्शित करता है। सबसे नया नंबर 0 होगा।
  • tmux शो-बफ़र -b (बफ़र संख्या) : यह किसी टर्मिनल पर दिए गए बफ़र की सामग्री को प्रिंट करता है
  • tmux पेस्ट-बफर -b (बफर संख्या) : यह इनपुट के रूप में दिए गए बफर की सामग्री को चिपकाता है

हाँ, इससे हमें बहुत संभावनाएँ मिलती हैं :) जैसा कि मेरे लिए, मैंने एक साधारण उपनाम स्थापित किया है: alias L="tmux capture-pane; tmux showb -b 0 | tail -n 3 | head -n 1"और अब हर बार मुझे अंतिम पंक्ति तक पहुंचने की आवश्यकता है जिसे मैं $(L)इसे प्राप्त करने के लिए उपयोग करता हूं ।

यह प्रोग्राम द्वारा उपयोग किए जाने वाले आउटपुट स्ट्रीम से स्वतंत्र है (यह स्टडिन या स्टैडर है), प्रिंटिंग विधि (ncurses, आदि) और प्रोग्राम का निकास कोड - डेटा को केवल प्रदर्शित करने की आवश्यकता है।


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

9

मुझे लगता है कि आप एक समाधान को हैक करने में सक्षम हो सकते हैं जिसमें आपके शेल को एक स्क्रिप्ट में सेट करना शामिल है:

#!/bin/sh
bash | tee /var/log/bash.out.log

फिर यदि आप $PROMPT_COMMANDएक सीमांकक आउटपुट के लिए सेट करते हैं, तो आप एक सहायक फ़ंक्शन (शायद कहा जाता है _) लिख सकते हैं जो आपको उस लॉग का अंतिम हिस्सा मिलता है, इसलिए आप इसका उपयोग कर सकते हैं:

% find lots*of*files
...
% echo "$(_)"
... # same output, but doesn't run the command again

7

आप अपनी प्रोफ़ाइल में निम्नलिखित उपनाम सेट कर सकते हैं:

alias s='it=$($(history | tail -2 | head -1 | cut -d" " -f4-))'

फिर, एक मनमाना आदेश के बाद 's' टाइप करके आप परिणाम को शेल चर 'इट' में सहेज सकते हैं।

इसलिए उदाहरण का उपयोग होगा:

$ which python
/usr/bin/python
$ s
$ file $it
/usr/bin/python: symbolic link to `python2.6'

धन्यवाद! यह वही है जो मुझे अपने grabकार्य को कार्यान्वित करने की आवश्यकता है जो कि nth लाइन को अंतिम कमांड से क्लिपबोर्ड gist.github.com/davidhq/f37ac87bc77f27c5027e
davidhq

6

मैंने इस bashकार्य को यहाँ के सुझावों से पूरा किया:

grab() {     
  grab=$("$@")
  echo $grab
}

फिर, आप बस करें:

> grab date
Do 16. Feb 13:05:04 CET 2012
> echo $grab
Do 16. Feb 13:05:04 CET 2012

अद्यतन : एक गुमनाम उपयोगकर्ता ने सुझाव दिया है echoकि printf '%s\n'जिसके पास यह फायदा है कि यह -eहड़पने वाले पाठ की तरह विकल्पों को संसाधित नहीं करता है । इसलिए, यदि आप ऐसी विशिष्टताओं की अपेक्षा या अनुभव करते हैं, तो इस सुझाव पर विचार करें। एक अन्य विकल्प cat <<<$grabइसके बजाय उपयोग करना है।


1
ठीक है, कड़ाई से यह कहना एक जवाब नहीं है क्योंकि, "स्वचालित" भाग पूरी तरह से गायब है।
तिलमन वोगेल

क्या आप cat <<<$grabविकल्प बता सकते हैं ?
leoj

1
इससे उद्धृत करते हुए man bash: "यहां के तार: यहां दस्तावेजों का एक प्रकार है, प्रारूप है: <<<wordशब्द का विस्तार और उसके मानक इनपुट पर कमांड को आपूर्ति की जाती है।" तो, मूल्य को स्टड पर $grabखिलाया जाता catहै, और catइसे वापस स्टडआउट खिलाता है।
तिलमन वोगेल

5

"मैं एक अंतिम आदेश में अंतिम निष्पादित कमांड के परिणाम का उपयोग करने में सक्षम होना चाहता हूं" कहकर, मैं मानता हूं - आपका मतलब किसी भी आदेश का परिणाम है, न कि केवल खोजें।

अगर यह मामला है - xargs वही है जो आप खोज रहे हैं।

find . -name foo.txt -print0 | xargs -0 -I{} mv {} /some/new/location/{}

या यदि आप पहले आउटपुट को देखने के इच्छुक हैं:

find . -name foo.txt -print0

!! | xargs -0 -I{} mv {} /some/new/location/{}

यह कमांड कई फाइलों से संबंधित है और पथ और / या फ़ाइल नाम स्थान होने पर भी एक आकर्षण की तरह काम करता है।

एमवी {} / कुछ / नया / स्थान / {} कमांड का हिस्सा नोटिस करें । यह कमांड पूर्व कमांड द्वारा मुद्रित प्रत्येक लाइन के लिए निर्मित और निष्पादित की जाती है। यहां पहले की कमांड द्वारा छपी लाइन को {} की जगह बदल दिया जाता है ।

Xargs के मैन पेज से अंश:

xargs - मानक इनपुट से कमांड लाइनों का निर्माण और निष्पादन

अधिक विवरण के लिए मैन पेज देखें: man xargs


5

Backticks के साथ आउटपुट कैप्चर करें:

output=`program arguments`
echo $output
emacs $output

4

मैं आमतौर पर वही करता हूं जो दूसरों ने यहां सुझाया है ... बिना असाइनमेंट के:

$find . -iname '*.cpp' -print
./foo.cpp
./bar.cpp
$vi `!!`
2 files to edit

आप पसंद कर सकते हैं अगर आप पसंद करते हैं:

$grep -R "some variable" * | grep -v tags
./foo/bar/xxx
./bar/foo/yyy
$vi `!!`

2

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

LAST=`!!`

तो आप के साथ उत्पादन पर अपनी कमांड चला सकते हैं:

yourCommand $LAST

यह एक नई प्रक्रिया को आगे बढ़ाएगा और आपकी कमांड को फिर से चलाएगा, फिर आपको आउटपुट देगा। ऐसा लगता है कि आप वास्तव में कमांड आउटपुट के लिए बैश इतिहास फ़ाइल क्या चाहते हैं। इसका मतलब है कि आपको अपने टर्मिनल पर भेजने वाले आउटपुट को कैप्चर करना होगा। आप / dev या / proc देखने के लिए कुछ लिख सकते हैं, लेकिन यह गड़बड़ है। आप अपने टर्म के बीच में एक "विशेष पाइप" भी बना सकते हैं और बीच में एक टी कमांड के साथ बैश कर सकते हैं जो आपकी आउटपुट फाइल पर रीडायरेक्ट करता है।

लेकिन ये दोनों एक तरह के हैकी सॉल्यूशन हैं। मुझे लगता है कि सबसे अच्छी बात टर्मिनेटर होगी जो आउटपुट लॉगिंग के साथ एक अधिक आधुनिक टर्मिनल है। अंतिम आदेश के परिणामों के लिए बस अपनी लॉग फ़ाइल की जाँच करें। उपरोक्त के समान बैश वैरिएबल यह और भी सरल बना देगा।


1

अपने आदेश को निष्पादित करने के बाद यह करने का एक तरीका यहां है और निर्णय लिया गया है कि आप परिणाम को एक चर में संग्रहीत करना चाहते हैं:

$ find . -name foo.txt
./home/user/some/directory/foo.txt
$ OUTPUT=`!!`
$ echo $OUTPUT
./home/user/some/directory/foo.txt
$ mv $OUTPUT somewhere/else/

या यदि आप समय से पहले जानते हैं कि आप एक चर में परिणाम चाहते हैं, तो आप backticks का उपयोग कर सकते हैं:

$ OUTPUT=`find . -name foo.txt`
$ echo $OUTPUT
./home/user/some/directory/foo.txt

1

मौजूदा उत्तरों के विकल्प के रूप में: whileयदि आपके फ़ाइल नामों में रिक्त स्थान हो सकते हैं तो इस तरह का उपयोग करें:

find . -name foo.txt | while IFS= read -r var; do
  echo "$var"
done

जैसा कि मैंने लिखा है, अंतर केवल तभी प्रासंगिक है जब आपको फ़ाइल नामों में रिक्तता की अपेक्षा करनी होगी।

एनबी: केवल निर्मित सामान आउटपुट के बारे में नहीं है, लेकिन अंतिम कमांड की स्थिति के बारे में है।


1

आप उपयोग कर सकते हैं !!: १। उदाहरण:

~]$ ls *.~
class1.cpp~ class1.h~ main.cpp~ CMakeList.txt~ 

~]$ rm !!:1
rm class1.cpp~ class1.h~ main.cpp~ CMakeList.txt~ 


~]$ ls file_to_remove1 file_to_remove2
file_to_remove1 file_to_remove2

~]$ rm !!:1
rm file_to_remove1

~]$ rm !!:2
rm file_to_remove2

यह नोटेशन एक कमांड से गिने हुए तर्क को पकड़ता है: "$ {पैरामीटर: ऑफसेट}" के लिए यहां दस्तावेज़ देखें: gnu.org/software/bash/manual/html_node/… । अधिक उदाहरणों के लिए यहां भी देखें: howtogeek.com/howto/44997/…
अलेक्जेंडर बर्ड

1

मुझे इसी तरह की आवश्यकता थी, जिसमें मैं पिछले कमांड के आउटपुट को अगले एक में उपयोग करना चाहता था। बहुत कुछ ए | (पाइप)। जैसे

$ which gradle 
/usr/bin/gradle
$ ls -alrt /usr/bin/gradle

कुछ इस तरह से -

$ which gradle |: ls -altr {}

समाधान: यह कस्टम पाइप बनाया गया। वास्तव में सरल, xargs का उपयोग कर -

$ alias :='xargs -I{}'

मूल रूप से xargs के लिए एक छोटा हाथ बनाने से कुछ नहीं होता है, यह आकर्षण की तरह काम करता है, और वास्तव में आसान है। मैं सिर्फ .bash_profile फ़ाइल में उपनाम जोड़ता हूं।


1

यह फ़ाइल डिस्क्रिप्टर और lastpipeशेल विकल्प के जादू का उपयोग करके किया जा सकता है ।

इसे एक स्क्रिप्ट के साथ करना होगा - इंटरैक्टिव मोड में "लास्टपाइप" विकल्प काम नहीं करेगा।

यहां वह स्क्रिप्ट दी गई है जिसका मैंने परीक्षण किया है:

$ cat shorttest.sh 
#!/bin/bash
shopt -s lastpipe

exit_tests() {
    EXITMSG="$(cat /proc/self/fd/0)"
}

ls /bloop 2>&1 | exit_tests

echo "My output is \"$EXITMSG\""


$ bash shorttest.sh 
My output is "ls: cannot access '/bloop': No such file or directory"

मैं यहाँ क्या कर रहा हूँ:

  1. खोल विकल्प सेट करना shopt -s lastpipe। यह इसके बिना काम नहीं करेगा क्योंकि आप फाइल डिस्क्रिप्टर खो देंगे।

  2. यह सुनिश्चित करने के साथ कि मेरा स्टैडर भी पकड़ लेता है 2>&1

  3. एक फ़ंक्शन में आउटपुट को पाइप करना ताकि स्टडिन फाइल डिस्क्रिप्टर को संदर्भित किया जा सके।

  4. /proc/self/fd/0फ़ाइल डिस्क्रिप्टर की सामग्री प्राप्त करके चर सेट करना , जो कि स्टडिन है।

मैं एक स्क्रिप्ट में त्रुटियों को कैप्चर करने के लिए इसका उपयोग कर रहा हूं, इसलिए यदि कोई कमांड के साथ कोई समस्या है तो मैं स्क्रिप्ट को संसाधित करना बंद कर सकता हूं और तुरंत बाहर निकल सकता हूं।

shopt -s lastpipe

exit_tests() {
    MYSTUFF="$(cat /proc/self/fd/0)"
    BADLINE=$BASH_LINENO
}

error_msg () {
    echo -e "$0: line $BADLINE\n\t $MYSTUFF"
    exit 1
}

ls /bloop 2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msg

इस तरह मैं 2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msgहर उस कमांड को जोड़ सकता हूँ जिसकी मुझे जाँच करनी है।

अब आप अपने आउटपुट का आनंद ले सकते हैं!


0

यह सख्ती से बैश समाधान नहीं है, लेकिन आप पिछली कमांड आउटपुट की अंतिम पंक्ति प्राप्त करने के लिए sed के साथ पाइपिंग का उपयोग कर सकते हैं।

पहले देखते हैं कि मेरे पास फ़ोल्डर "a" में क्या है

rasjani@helruo-dhcp022206::~$ find a
a
a/foo
a/bar
a/bat
a/baz
rasjani@helruo-dhcp022206::~$ 

फिर, ls और cd के साथ आपका उदाहरण sed और पाइपिंग में कुछ इस तरह से बदल जाएगा:

rasjani@helruo-dhcp022206::~$ cd `find a |sed '$!d'`
rasjani@helruo-dhcp022206::~/a/baz$ pwd
/home/rasjani/a/baz
rasjani@helruo-dhcp022206::~/a/baz$

तो, वास्तविक जादू सेड के साथ होता है, आप कभी भी क्या पाइप का उत्पादन करते हैं जो कभी भी सेड में कमांड करता है और अंतिम पंक्ति को प्रिंट करता है जिसे आप बैक टिक के साथ पैरामीटर के रूप में उपयोग कर सकते हैं। या आप इसे xargs से भी जोड़ सकते हैं। (शेल में "आदमी xargs" आपका मित्र है)


0

शेल में पर्ल-जैसे विशेष प्रतीक नहीं होते हैं जो अंतिम कमांड के इको रिजल्ट को स्टोर करते हैं।

जाग के साथ पाइप प्रतीक का उपयोग करना सीखें।

find . | awk '{ print "FILE:" $0 }'

ऊपर दिए गए उदाहरण में आप यह कर सकते हैं:

find . -name "foo.txt" | awk '{ print "mv "$0" ~/bar/" | "sh" }'

0
find . -name foo.txt 1> tmpfile && mv `cat tmpfile` /path/to/some/dir/

अभी तक एक और तरीका है, यद्यपि गंदा।


खोजो। -name foo.txt 1> tmpfile && mv `बिल्ली tmpfile` पथ / से / कुछ / dir && rm tmpfile
केविन

0

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

इस एक के साथ लाभ यह है कि आपको पूरे कमांड को फिर से चलाने की ज़रूरत नहीं है (जब उपयोग findया अन्य लंबे समय से चलने वाले कमांड महत्वपूर्ण हो सकते हैं)

काफी सरल, अपने में यह चिपकाएँ .bash_profile:

लिपि

# catch stdin, pipe it to stdout and save to a file
catch () { cat - | tee /tmp/catch.out}
# print whatever output was saved to a file
res () { cat /tmp/catch.out }

प्रयोग

$ find . -name 'filename' | catch
/path/to/filename

$ res
/path/to/filename

इस बिंदु पर, मैं | catchअपने सभी आदेशों के अंत में बस जोड़ना चाहता हूं, क्योंकि ऐसा करने की कोई कीमत नहीं है और यह मुझे आदेशों को फिर से चलाने के लिए बचाता है जो समाप्त होने में लंबा समय लेते हैं।

इसके अलावा, यदि आप एक पाठ संपादक में फ़ाइल आउटपुट खोलना चाहते हैं, तो आप ऐसा कर सकते हैं:

# vim or whatever your favorite text editor is
$ vim <(res)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.