स्क्रीन पर रखते समय स्टडआउट को पाइप कैसे करें? (और आउटपुट फाइल में नहीं)


234

मैं इसे स्क्रीन पर रखते हुए एक कार्यक्रम के मानक आउटपुट को पाइप करना चाहूंगा।

एक साधारण उदाहरण के साथ ( echoयहाँ उपयोग सिर्फ दृष्टांत प्रयोजन के लिए है):

$ echo 'ee' | foo
ee <- आउटपुट मैं देखना चाहूंगा

मुझे पता है कि टी फाइल करने के लिए स्टडआउट की प्रतिलिपि बना सकता है लेकिन यह वह नहीं है जो मैं चाहता हूं।
$ echo 'ee' | tee output.txt | foo

मैंने कोशिश की
$ echo 'ee' | tee /dev/stdout | fooलेकिन यह काम नहीं करता है क्योंकि टी आउटपुट को /dev/stdoutपाइप किया जाता हैfoo


6
ध्यान दें कि echo 'ee' | tee /dev/stderrहालांकि काम करता है, इसलिए यदि आपकी "ऑन स्क्रीन" आवश्यकता, stderr से भी संतुष्ट है, तो वह करेंगे।
nh2

जवाबों:


344

यहां एक समाधान है जो किसी भी यूनिक्स / लिनक्स कार्यान्वयन पर काम करता है, यह मानते हुए कि यह POSIXमानक का पालन करता है। यह कुछ गैर यूनिक्स वातावरण पर भी काम करता cygwinहै।

echo 'ee' | tee /dev/tty | foo

संदर्भ: ओपन ग्रुप बेस स्पेसिफिकेशन्स अंक 7 IEEE Std 1003.1, 2013 संस्करण, Open10.1 :

/ Dev / tty

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

Google Colab जैसे कुछ वातावरणों /dev/ttyको अभी भी लागू नहीं होने की सूचना दी गई है, जबकि उनकी ttyकमान एक प्रयोग करने योग्य उपकरण को लौटा रही है। यहाँ एक समाधान है:

tty=$(tty)
echo 'ee' | tee $tty | foo

या प्राचीन बोर्न शेल के साथ:

tty=`tty`
echo 'ee' | tee $tty | foo

5
@static_rtti आपकी टिप्पणी के उत्तर के बाद आप साल दर साल क्यों अनदेखा कर रहे हैं?
jlliagre

1
@PaulBissex /dev/ttyएक अनिवार्य यूनिक्स डिवाइस है। क्या आप बीएसडी जेल में चल रहे हैं?
जलेगीरे २

1
@PaBBissex यह एक कार्यान्वयन या एक कॉन्फ़िगरेशन बग है। / देव घुड़सवार है? क्या दिखाता है "ls -l / dev / tty / dev / tty * / dev"? देखें lists.freebsd.org/pipermail/freebsd-bugs/2012-November/... forums.freebsd.org/threads/...
jlliagre

1
और आप teeइस तरह से कैसकेड कर सकते हैं : cat some.log | tee /dev/tty | tee -a other.log | grep -i 'foo' >> foo.log1 से) यह सब कंसोल को प्राप्त करें, 2) इसे सभी को किसी अन्य फाइल से जोड़ दें, 3) fooएक अलग फाइल पर लाइन्स प्राप्त करें ।
जेसी चिशोल्म

1
Google Colab में नहीं है /dev/tty, लेकिन ttyइसका उपयोग करने योग्य है।
टॉम हेल

69

कोशिश करने के लिए एक और बात है:

echo 'ee' | tee >(foo)

>(foo)एक है प्रक्रिया प्रतिस्थापन


1
क्या होगा अगर मैं फू के आउटपुट को किसी अन्य बार में पाइप करना चाहता हूं?
जैक तांग

3
@JackTang - मुझे लगता है कि आगे के आउटपुट पर किसी भी तरह की पाइपिंग fooप्रक्रिया के प्रतिस्थापन का हिस्सा बनना होगा। यहाँ एक उदाहरण है:echo 'ee' | tee file.txt >(wc -c | tr -d ' ')
निक चामास

1
यह मेरे लिए FreeBSD (कोई / देव / tty) पर समाधान नहीं था
पॉल बिसेक्स

9
@Nick Chammas, एक सामान्य पाइपलाइन को बनाए रखने के लिए, आप टी के आउटपुट स्वैप कर सकते हैं: echo 'ee' | tee >(cat) | foo | bar
वीलस

18

कुछ सिस्टम पर "/ dev / stdout" तक पहुंच से वंचित किया गया है, लेकिन उपयोगकर्ता टर्मिनल तक पहुंच "/ dev / tty" द्वारा दी गई है। "Foo" के लिए "wc" का उपयोग करते हुए, उपरोक्त उदाहरण ठीक काम करते हैं (linux, OSX, आदि पर) जैसे:

% echo 'Hi' | tee /dev/tty | wc Hi 1 1 3

मेल खाने वाली फ़ाइलों की सूची के नीचे एक गिनती जोड़ने के लिए, मैं कुछ इस तरह का उपयोग करता हूं:
% ls [A-J]* | tee /dev/tty | wc -l

यह सब याद रखने से बचने के लिए, मैं उपनाम परिभाषित करता हूं:
% alias t tee /dev/tty
% alias wcl wc -l

ताकि मैं बस कह सकूं:
% ls [A-J]* | t | wcl


POSTSCRIPT: छोटे सेट के लिए, जो "टिट्टी" के रूप में इसके उच्चारण में कड़वा हो सकता है, मैं जोड़ सकता हूं कि "ट्टी" एक "टेलेटाइप" टर्मिनल के लिए एक सामान्य संक्षिप्त नाम था, जिसमें पीले पेपर के रोल का उपयोग किया गया था और इसमें अक्सर गोल कुंजी होती थीं। अटक गया।


17

प्रयत्न:

$ echo 'ee' | tee /dev/stderr | foo

यदि stderr का उपयोग करना एक विकल्प है, तो निश्चित रूप से।


8

सबसे पहले आपको अपनी स्क्रीन से जुड़े टर्मिनल का पता लगाने की जरूरत है (या जो भी स्क्रीन आप आउटपुट दिखाना चाहते हैं):

tty

तब आप उस टर्मिनल पर आउटपुट को भेज सकते हैं और अपने foo प्रोग्राम के माध्यम से दूसरी कॉपी को पाइप कर सकते हैं:

echo ee | tee /dev/pty/2 | foo

1
oneliner: t = $ (tty) गूंज ee | ते $ त | फू | बार
जैक तांग

5
@JackTang यह वास्तव में बेहतर है लेकिन tबेकार है। आप उपयोग कर सकते हैं echo ee | tee $(tty) | fooलेकिन इसमें अभी भी एक बेकार कमांड ( tty) है, जो कि /dev/ttyसिर्फ काम करता है।
जूलियाग्रे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.