एक कार्यक्रम के मानक इनपुट को दूसरे के लिए एक arg के रूप में कैसे पारित किया जा सकता है?


17

मान लीजिए कि एक प्रोग्राम मौजूद है, जो दो तर्क देता है; इनपुट फ़ाइल और आउटपुट फ़ाइल।

क्या होगा अगर मैं इस आउटपुट फ़ाइल को डिस्क पर सहेजना नहीं चाहता, बल्कि इसे सीधे stdinकिसी अन्य प्रोग्राम में पास कर दूं । क्या इसको हासिल करने के लिए कोई रास्ता है?

लिनक्स पर आने वाली बहुत सारी कमांड आउटपुट फाइल तर्क के रूप में '-' पास करने का विकल्प प्रदान करती है, जो कि मैंने ऊपर निर्दिष्ट किया है। क्या ऐसा इसलिए है क्योंकि stdinएक कार्यक्रम को एक तर्क के रूप में पारित करना संभव नहीं है? यदि यह है, तो हम इसे कैसे करते हैं?

इसका उपयोग करने के लिए मैं कैसे छवि का एक उदाहरण है:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)

मैं जिस शेल का उपयोग कर रहा हूं वह बैश है।


1
cat <file | cmd /dev/fd/0अधिकांश यूनियनों पर काम करता है।
mikeserv

मेरे लिए काम नहीं कर रहा है। इसके साथ की कोशिश की cat < README.txt | cp /dev/fd/0:। यह कहा गयाcp: missing destination file operand after ‘/dev/fd/0’ Try 'cp --help' for more information.
डिजीगस

1
program input-file /dev/stdout | another-program? यह भी ध्यान दें कि echoस्टड से कुछ भी नहीं पढ़ता है।
ययगाशी

1
@Dziugas - बिल्कुल नहीं - आप cpकहीं भी फाइल नहीं कर सकते । echo 1 2 3| cp /dev/fd/0 /dev/ttyछप जाएगा 1 2 3। और वैसे, अधिकांश मामलों की /dev/fd/[num]तुलना /dev/std(in|out|err)में काम करने की अधिक संभावना है । फ़ाइल-डिस्क्रिप्टर लिंक की पोर्टेबिलिटी देखें कि आप कहाँ काम करने की उम्मीद कर सकते हैं।
मिकसेर्व जूल

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

जवाबों:


13

यदि प्रोग्राम किसी फ़ाइल डिस्क्रिप्टर पर लिखने का समर्थन करता है, भले ही वह खोज नहीं कर सकता है, तो आप /dev/stdoutआउटपुट फ़ाइल के रूप में उपयोग कर सकते हैं । यह /proc/self/fd/1मेरे सिस्टम पर एक सहानुभूति है। फ़ाइल डिस्क्रिप्टर 1 stdout है।


इससे मेरी क्वेरी हल हो गई। तो क्या ऐसा करने का कोई तरीका नहीं है जब कार्यक्रम की आवश्यकता है?
डाइजुगास

3
यदि आप डिस्क एक्सेस को रोकने की कोशिश कर रहे हैं, तो आप फ़ाइल को / dev / shm / में लिख सकते हैं, हालाँकि, यदि आप फाइल सिस्टम पर कोई फ़ाइल नहीं चाहते हैं, तो जहाँ तक मुझे पता है, वहाँ कोई रास्ता नहीं है। एक पाइप। आगे की तलाश का मतलब यह है कि जब तक यह उस बिंदु तक नहीं पहुंच जाता तब तक सब कुछ बफर करना होगा, और पिछड़े की तलाश में स्मृति में सब कुछ बफ़र करना होगा।
TiCPU

pdftotextजैसे कई (लेकिन सभी नहीं) अन्य उपयोगिताओं -उस के लिए भी समर्थन करती हैं (जो उन प्रणालियों पर भी काम करेगी जो समर्थन नहीं करते / dev / stdout, या जहां / dev / stdout लिनक्स पर अपेक्षित रूप से काम नहीं करते हैं जहां stdout नहीं है एक पाइप)। pdftotext file.pdf - | wc -c
स्टीफन चेजलस

11

से pdftotextआदमी पेज:

यदि पाठ-फ़ाइल ´- 'है, तो पाठ को stdout में भेजा जाता है।

तो इस मामले में आप सभी की जरूरत है:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" -

या यदि आप इसे किसी अन्य प्रोग्राम के STDIN पर पाइप करना चाहते हैं:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" - | another_prog

-फ़ाइल नाम के विकल्प के रूप में उपयोग करना एक कन्वेंशन है, जब हम STDIN से इनपुट या आउटपुट से STDOUT में इनपुट चाहते हैं, तो कई उपयोगिताओं (pdftotext सहित) का पालन करते हैं। हालांकि सभी उपयोगिताओं इस सम्मेलन का पालन नहीं करती हैं। उस स्थिति में इस तरह से काम करने के लिए मुहावरेदार तरीका एक प्रक्रिया प्रतिस्थापन का उपयोग करना है :

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( cat )

यहाँ >( )काफी हद तक एक फ़ाइल की तरह व्यवहार किया जाता है my_utility, लेकिन एक वास्तविक फ़ाइल होने के बजाय, स्ट्रीम को निहित प्रक्रिया के स्टैड में पाइप किया जाता है, अर्थात बिल्ली। इसलिए यहां, पाठ को अंततः आवश्यकतानुसार आउटपुट देना चाहिए।

उपयोग की catलगभग हमेशा बंद सेट UUOC अलार्म की घंटी इस तरह के मंचों पर। मैं तर्क देता हूं कि यदि उपयोगिता समर्थन नहीं करती है -, तो यह एक उपयोगी उपयोग है cat, हालांकि अगर इस प्रक्रिया को प्रतिस्थापन के बिना करने के लिए कोई भी तरीके हैं cat, तो मैं सभी कान हूं ;-)।

हालाँकि, यदि (जैसा कि प्रश्न कहता है) स्ट्रीम का अंतिम गंतव्य किसी अन्य प्रोग्राम का STDIN है, तो catइसे समाप्त किया जा सकता है:

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( another_prog )

2
और मुझे एक बार फिर से बैकपेडल करना चाहिए: अगर prog2स्टडआउट को लिखता है, तो इससे बेहतर है , क्योंकि फॉर्म का इंतजार हैprog1 input_file >( cat ) | prog2prog1 input_file >( prog2 )catprog2 पूरा का (यानी, शेल अगले प्रॉम्प्ट को जारी करने से पहले या अगले कमांड पर जाता है (जैसे, बाद ;या &&)), जबकि cat-विहीन फॉर्म केवल prog1पूरा होने का इंतजार करता है । इसके अलावा, catफॉर्म के बाद , $?से बाहर निकलने की स्थिति है prog2, जबकि, दूसरे में, $?से बाहर निकलने की स्थिति है prog1। (आप अपने पैसे का भुगतान करते हैं और आप अपनी पसंद लेते हैं।)
स्कॉट

4

यदि आपका शेल उन्हें समर्थन देता है, तो इस तरह की जोड़तोड़ करने का सबसे सरल तरीका प्रक्रिया प्रतिस्थापन का उपयोग करना होगा : <(…)और >(…)। यह बाश, zsh और ksh और संभवतः अन्य गोले में काम करता है। उदाहरण के लिए:

$ sort <(printf "b\nc\na\n")
a
b
c
$ ls
foo
$ cp <(find . -name foo) bar
$ ls
bar  foo

हालाँकि, यह आपके द्वारा बताए गए उदाहरण में मदद नहीं करेगा क्योंकि pdftotextपाठ फ़ाइल में सहेजा जाएगा। जबकि आपकी सबसे अच्छी पसंद (स्पष्ट रूप -से उपयोग करने के अलावा) /dev/stdout@TiCPU द्वारा सुझाई गई है, आप किसी अन्य शेल सुविधा का भी उपयोग कर सकते हैं। निर्माण !:Nपिछले कमांड के Nth तर्क को संदर्भित करता है। इसलिए, आप कर सकते हैं:

$ pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"  out.txt
$ cat !:2

1
जबकि मैं मानता हूं कि cat <()कुछ स्थितियों में उपयोगी हो सकता है, इस परिदृश्य में हालांकि यह बिल्कुल भी काम नहीं कर रहा है। समस्या (बहुत खराब रूप से ओपी द्वारा वर्णित, मुझे मानना ​​चाहिए) pdftotextदो तर्क हैं: इनपुट फ़ाइल और आउटपुट फ़ाइल । यदि दूसरा तर्क गायब है तो यह कुछ भी नहीं पैदा करता है, इसलिए cat <(pdftotext "file.pdf")कुछ भी नहीं लौटाएगा। डिजिटल ट्रॉमा pdftotextद्वारा दिए गए >(cat)उत्तर की तरह दूसरा तर्क देकर कोई भी कमांड को धोखा दे सकता है , लेकिन cat <()यहां व्यर्थ है। जाहिर है अंदरpdftotext यह केवल -आउटपुट फाइल नाम के रूप में उपयोग करने के लिए सबसे अच्छा है ।
jimmij

1
@ उत्तर यूयूओसी कैसे है? आप बिल्ली के बिना इस प्रक्रिया का प्रतिस्थापन कैसे करेंगे? >( )प्रभावी रूप से स्ट्रीम को पाइप करेगा जो भी प्रक्रिया के अंदर है - इसलिए हमें वास्तव में catउस स्ट्रीम को आउटपुट करने के लिए यहां की आवश्यकता है । आम तौर पर हमें कुछ ऐसा करने में सक्षम होना चाहिए pdftotext input.pdf -, लेकिन स्पष्ट रूप से एक फ़ाइल के बजाय सीधे आउटपुट के pdftotextलिए -पैरामीटर का समर्थन नहीं करता है - इसे आज़माएं।
डिजिटल ट्रामा

1
@DigitalTrauma यह यूओक नहीं है। मेरा मानना ​​है कि बिल्ली सबसे तेज़ है जो आप सिर्फ मुद्रण के मामले में प्राप्त कर सकते हैं, लेकिन वास्तव में आप >(grep something)अधिक उपयोगी होने के लिए अन्य कमांड का उपयोग कर सकते हैं । BTW, मेरी pdftotext 3.04 करते समर्थन -कोई आउटपुट फ़ाइल के रूप में, तो मैं कर रहा हूँ एक छोटे से पूरे चर्चा से हैरान।
jimmij

1
@terdon मैं एक स्टिकर होने से नफरत करता हूं, लेकिन यह काम नहीं करता है। विशेष रूप से यह अलग नहीं है कि चल रहा है pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf", जो आउटपुट को एक फ़ाइल में रखता है जिसे कहा जाता है C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.txt, लेकिन कोई भी पाठ दूसरे प्रोग्राम में पाइपिंग के लिए STDOUT के लिए आउटपुट नहीं है।
डिजिटल ट्रामा

1
@DigitalTrauma जो एक स्टिकर नहीं है! वह एक बेवकूफ है। इसे इंगित करने के लिए धन्यवाद और गलतियों को इंगित करते समय कृपया कभी क्षमा न करें। मैं अपनी गलती के बारे में बहुत कुछ बताऊंगा और इसलिए इसे अपने सभी संदिग्ध महिमा में वहां छोड़ने से कुछ सीखूंगा।
terdon

-2
cmd tty

ttyसे जुड़े टर्मिनल का नाम देता है stdout


मुझे यकीन नहीं है कि यह सवाल का जवाब कैसे देता है, जो कमांड के संयोजन के बारे में है; शायद आप इसका उदाहरण देंगे कि आप इसे कैसे हासिल करेंगे।
ढिग

मुझे लगता है कि आप ttyटर्मिनल के नाम के साथ जांच करने के लिए कह रहे हैं , और फिर आउटपुट के रूप में उस फ़ाइल का उपयोग करें pdftotext file.pdf /dev/pts/2। उस मामले में, मैं सहमत हूं।
jimmij

जिसे संक्षिप्त / स्वचालित किया जा सकता है ; जो आम तौर पर इसके बराबर होने जा रहा है । लेकिन यह दृष्टिकोण मानता है कि लक्ष्य (यानी टर्मिनल में) के आउटपुट को प्रदर्शित करना है , और यह वह नहीं है जो सवाल पूछ रहा है (सवाल के अर्थ पर कुछ स्पष्टीकरण के लिए टेर्डन के जवाब पर टिप्पणी देखें )। prog1  input_file $(tty)prog1  input_file /dev/ttyprog1
स्कॉट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.