अस्थायी फ़ाइलों के बिना दो प्रोग्रामों से डिफ आउटपुट


145

मैं भी कार्यक्रम है कहो aऔर bमैं के साथ चला सकते हैं कि ./aऔर ./b

क्या अस्थायी फ़ाइलों को लिखे बिना उनके आउटपुट को अलग करना संभव है?


जवाबों:


211

<(command)एक कमांड के आउटपुट को दूसरे प्रोग्राम में पास करने के लिए उपयोग करें जैसे कि यह एक फ़ाइल नाम था। बैश पाइप के प्रोग्राम के आउटपुट को पाइप करता है और /dev/fd/63बाहरी कमांड की तरह एक फ़ाइल नाम देता है ।

diff <(./a) <(./b)

इसी तरह >(command)यदि आप किसी कमांड में कुछ पाइप करना चाहते हैं तो आप इसका उपयोग कर सकते हैं ।

इसे बैश के मैन पेज में "प्रोसेस सब्स्टीट्यूशन" कहा जाता है।


1
इसके बारे में पता करने के लिए एक दोष यह है कि अगर ./a या ./b विफल रहता है, तो कॉलर को यह पता नहीं चलेगा।
अलेक्जेंडर पोगरेबनेक

5
ओपी ने प्रश्न को टाल दिया, लेकिन रिकॉर्ड के लिए, यह किसी अन्य शेल में काम नहीं करता है। यह Posix उपयोगिता मानक के लिए एक bash एक्सटेंशन है।
DigitalRoss

5
मैंने जावा प्रोग्राम के साथ इस समाधान की कोशिश की और यह त्रुटि मिली -bash: syntax error near unexpected token (':। मैंने बिना कोष्ठक के फिर से कोशिश की और मिल गया -bash: java: No such file or directory। यदि कमांड में पैरामीटर हैं तो क्या यह काम नहीं करता है?
स्टाइलफ्लेक्स

1
@DigitalRoss - समाधान अन्य गोले के लिए एक उपनाम का उपयोग करके बढ़ाया जा सकता है। Tcsh में, निम्नलिखित कुरूपता काम करती है alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\':। (फिर उदाहरण के लिए: diffcmd "ls" "ls -a")।
पॉल लिंच

Google से भटकने वाले किसी व्यक्ति के लिए, यह zsh के अंतर्गत भी काम करता है। (इसके अलावा, अगर आपको किसी ऐसी चीज में इनपुट फीड करना है fseek, जो zsh ऑफ़र की =(./a)पहचान के लिए इस्तेमाल की जा सकती है, <(./a)लेकिन हुड के नीचे एक अस्थायी फ़ाइल का उपयोग करता है, जो zsh आपके लिए हटा देगा।)
ssokolow

26

दोनों उत्तरों को जोड़ते हुए, यदि आप एक पक्ष को तुलना करके देखना चाहते हैं, तो उपयोग करें vimdiff:

vimdiff <(./a) <(./b)

कुछ इस तरह:

यहाँ छवि विवरण दर्ज करें


vimdiffसुंदर, स्मार्ट और इंटरैक्टिव अंतर तुलनात्मक विचार पैदा करता है। यह vimज्यादातर सिस्टम पर पैकेज के साथ आता है ।
टिम विज़े

vimdiffयह न केवल अलग-अलग रेखाओं को दिखाता है बल्कि विशिष्ट पाठ खंड को भी अलग करता है।
एंटोन तारासेंको 12

20

एक विकल्प नामित पाइप (एफआईएफओ) का उपयोग करना होगा :

mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo

... लेकिन जॉन कुगेलमैन का समाधान ज्यादा साफ है।


बेहतर होगा कि आप नामित पाइपों को इस्तेमाल करने के बाद हटा दें rm a_fifo b_fifo
फ्रैंकलिन यू

15

जिज्ञासु किसी के लिए, यह इस प्रकार है कि आप मछली के खोल का उपयोग करके प्रक्रिया प्रतिस्थापन करते हैं :

दे घुमा के:

diff <(./a) <(./b)

मछली:

diff (./a | psub) (./b | psub)

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


यह वर्तमान में मछली में सही ढंग से काम नहीं करता है। यदि प्रोग्राम का आउटपुट एक BUFSIZ से अधिक है, तो कमांड लटकाएगा। (या मछली वास्तव में सिर्फ डिस्क पर एक अस्थायी फ़ाइल का उपयोग करेगी)
इवान बेने

7

पहले से ही अच्छे उत्तरों के लिए थोड़ा और जोड़ना (मेरी मदद की!):

कमांड dockerइसकी मदद को आउटपुट करता है STD_ERR(यानी फाइल डिस्क्रिप्टर 2)

मैं अगर देखना चाहता था docker attachऔर docker attach --helpएक ही आउटपुट दे दी है

$ docker attach

$ docker attach --help

केवल उन दो आदेशों को टाइप करने के बाद, मैंने निम्नलिखित कार्य किया:

$ diff <(!-2 2>&1) <(!! 2>&1)

!! -1 के समान है, जिसका अर्थ है कि कमांड 1 को इस एक से पहले चलाएं - अंतिम कमांड

! -2 का मतलब है कि इस से पहले कमांड दो चलाएं

2> और 1 का अर्थ है file_descriptor 2 आउटपुट (STD_ERR) को उसी स्थान पर भेजें जैसे file_descriptor 1 आउटपुट (STD_OUT)

आशा है कि यह कुछ काम का रहा होगा।


0

Zsh के लिए, =(command)स्वचालित रूप से एक अस्थायी फ़ाइल बनाता है और फ़ाइल =(command)के पथ के साथ बदल देता है। सामान्य प्रक्रिया प्रतिस्थापन के $(command)साथ , कमांड के आउटपुट के साथ बदल दिया जाता है ।

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

bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)

तुलना से परे, ध्यान दें कि तुलना शुरू करने और उसके पूरा होने का इंतजारbcomp करने के bcompareबाद से आपको ऊपर (इसके बजाय ) का उपयोग करना चाहिए । यदि आप उपयोग करते हैं , तो वह तुलना शुरू करता है और तुरंत बाहर निकलता है जिसके कारण कमांड के आउटपुट को स्टोर करने के लिए बनाई गई अस्थायी फाइलें गायब हो जाती हैं।bcompbcompare

यहां पढ़ें: http://zsh.sourceforge.net/Intro/intro_7.html

यह भी ध्यान दें:

ध्यान दें कि शेल एक अस्थायी फ़ाइल बनाता है, और कमांड समाप्त होने पर इसे हटा देता है।

और जिसके बाद बीच का अंतर है $(...)और =(...):

यदि आप zsh का मैन पेज पढ़ते हैं, तो आप देख सकते हैं कि <(...) प्रक्रिया प्रतिस्थापन का दूसरा रूप है जो = (...) के समान है। दोनों के बीच एक महत्वपूर्ण अंतर है। <(...) मामले में, शेल एक फ़ाइल के बजाय एक नामित पाइप (FIFO) बनाता है। यह बेहतर है, क्योंकि यह फ़ाइल सिस्टम को नहीं भरता है; लेकिन यह सभी मामलों में काम नहीं करता है। वास्तव में, यदि हमने ऊपर के उदाहरणों में <(...) के साथ = (...) को प्रतिस्थापित किया होता, तो उन सभी को fgrep -f <(...) को छोड़कर काम करना बंद कर दिया होता। आप एक पाइप को संपादित नहीं कर सकते हैं, या इसे मेल फ़ोल्डर के रूप में खोल सकते हैं; हालाँकि, fgrep को पाइप से शब्दों की सूची पढ़ने में कोई समस्या नहीं है। आप आश्चर्यचकित हो सकते हैं कि अलग क्यों <(foo) बार काम नहीं करता है, क्योंकि foo | diff - बार काम करता है; इसका कारण यह है कि यदि कोई यह तर्क देता है कि यह एक अस्थायी फ़ाइल है, तो यह एक अस्थायी फ़ाइल बनाता है - और फिर इसके मानक इनपुट को अस्थायी फ़ाइल में कॉपी कर देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.