2010-11-03 11 views
6

मेरे पास किसी तीसरे पक्ष (यह जावा में बड़ा और लिखा गया है) से कमांड लाइन उपयोगिता है जिसे मैं कुछ डेटा संसाधित करने में मदद के लिए उपयोग कर रहा हूं। यह उपयोगिता एक लाइन सीमांकित फ़ाइल में जानकारी की अपेक्षा करती है और फिर संसाधित डेटा को STDOUT तक आउटपुट करती है।क्या यूनिक्स में किसी प्रोग्राम में फ़ाइल के बजाय stdin/out की आपूर्ति करने का कोई तरीका है?

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

bin/someapp do-action --option1 some_value --input $piped_in_data

कि संभव ऐसा कुछ है:

bin/someapp do-action --option1 some_value --input some_file

मैं की तरह कुछ करने के लिए करना चाहते हैं:

वर्तमान में मैं उपयोगिता के रूप में इस फोन एप्लिकेशन?

+0

स्टैक एक्सचेंज पर एक बहुत अधिक व्यापक उत्तर है, । – weynhamz

उत्तर

10

आप/dev/stdin उपयोग करने के लिए सक्षम होना चाहिए:

bin/someapp do-action --option1 some_value --input /dev/stdin 

(कि कुछ सिस्टम पर ध्यान दें,/dev/stdin एक सिमलिंक है, अगर आपके जावा प्रोग्राम है जो के साथ सामना नहीं है, आप हो सकता है इसके बजाय/dev/fd/0 या इसके समान कुछ उपयोग करना होगा।)

+0

तो मैं किस बिंदु पर डेटा को stdin पर भेजूं? मैं इसे कॉल करने के बाद इसके लिए इंतजार करूँगा? या मैं इसे हाथ से तुरंत करूँगा? यह वास्तव में कैसे काम करेगा? – Eli

+0

इसे सामान्य पाइपलाइन में उपयोग करें: 'gener_data.pl | bin/someapp do-action --option1 some_value --input/dev/stdin' –

+0

बहुत बढ़िया। यह वही है जो मैं चाहता था। – Eli

10

आप जो कुछ भी चाहते हैं उसे प्राप्त करने के लिए आप "प्रक्रिया प्रतिस्थापन" का उपयोग कर सकते हैं।

bin/someapp do-action --option1 some_value --input <(generate_input.sh) 

चाल चलाना चाहिए। <(list) हिस्सा प्रक्रिया प्रतिस्थापन है।

+0

मीठा! क्या वहां एक पर्ल स्क्रिप्ट का उपयोग करने का कोई तरीका है? परीक्षण करने के लिए, मैंने कोशिश की: गूंज <(perl -e 'print "yo;"'), लेकिन ऐसा लगता है कि यह काम नहीं कर रहा था। – Eli

+0

इसके बजाय प्रयास करें: बिल्ली - <<(perl -le 'print "yo"') :) – pavel

+0

या बस 'cat <(perl whatever)'। <(...) बिट एक फ़ाइल के नाम से प्रतिस्थापित हो जाता है जो जेनरेट किए गए डेटा पर पाइप का प्रतिनिधित्व करता है। 'echo' फ़ाइलों से पढ़ने के बारे में नहीं जानता है, लेकिन 'cat' करता है। –

2

एक और मार्ग, यदि /dev/stdin तकनीक किसी कारण से उपयुक्त नहीं है, तो 'नामित पाइप' का उपयोग करना है।

आप

% mkfifo /path/to/file 

करते हैं तो यह है कि नाम है, जो दो प्रक्रियाओं के बीच एक नाली के रूप में कार्य कर सकते हैं के साथ एक फाइल सिस्टम वस्तु का निर्माण करेगा। यह सामान्य पाइप के साथ क्या होता है, वही है, सिवाय इसके कि प्रक्रियाएं पाइप को संदर्भित कर सकती हैं जैसे कि यह एक सामान्य फ़ाइल थी। उदाहरण के लिए:

% mkfifo /tmp/my-fifo 
% grep alias ~/.bashrc >/tmp/my-fifo & 
[1] 70134 
% sed 's/alias/wibble/' /tmp/my-fifo 
wibble ls='ls -F' 
.... 
[1] + done  grep alias ~/.bashrc > /tmp/my-fifo 
% 

यहाँ, grep आदेश ब्लॉक फीफो लिए लिख रहा है बिल्कुल के रूप में अगर यह एक सामान्य फाइल थे, और यह जब नामित पाइप के बफर को भरती है। sed प्रक्रिया पाइप से पढ़ती है (जैसे कि यह एक सामान्य फ़ाइल थी), बफर को खाली करते हुए ऐसा करता है।

2

यह इतना आसान नहीं है।/dev/stdin, नामित पाइप और <() प्रक्रिया प्रतिस्थापन एक फ़ाइल द्वारा उसी तरह से एक फ़ाइल द्वारा उपयोग नहीं किया जाता है। विशेष रूप से इस तरह के निर्माण के भीतर fseek(), fsetpos() को संभव नहीं है, क्योंकि इसकी लंबाई प्राथमिकता नहीं है।

कुछ फ़ंक्शन जैसे fopen(), getc(), fread() आदि काम करेंगे। तो अधिकांश कार्यक्रमों के लिए जो चरित्र द्वारा लाइन या चरित्र द्वारा इनपुट लाइन को आसानी से पढ़ते हैं, ऐसा करेंगे।

यदि आपका प्रोग्राम किसी फ़ाइल में खोजता है (और शायद अन्य "अधिक उन्नत" संचालन करता है) तो आपको दुर्भाग्यवश एक अस्थायी फ़ाइल बनाना होगा।

संबंधित मुद्दे

 संबंधित मुद्दे