अस्थायी डेटा के लिए छद्म फ़ाइलें


98

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


क्या इसके माध्यम से हल किया जा सकता है xargs?
NN

नहीं पता, लेकिन यह मेरे लिए स्पष्ट नहीं होगा कि कैसे। जहाँ तक मैं समझता हूँ xargsकमांड के लिए फ़ाइल स्ट्रिंग तर्कों से इनपुट लाइनें बनाएगा। लेकिन मुझे इसके विपरीत चाहिए।
11

@ इल्मू मैं एक नज़र था, लेकिन मुझे लगता है कि समस्या की स्थापना वहां थोड़ी अलग है। कम से कम मैं यह नहीं देखता कि उत्तर कैसे मदद करेंगे। अस्थायी रूप से फ़ाइलों का उत्पादन करने के लिए स्वीकृत उत्तर अनिवार्य रूप से वही है जो मैं बचने के लिए नहीं चाहता, अगर नहीं तो किसी प्रकार का बफरिंग जो वास्तव में फाइलों को लिखने से रोकता है। मुझे इस बात की सीमित समझ है कि अस्थायी फाइलें कैसे काम करती हैं!
highsciguy

इसमें गलत क्या है echo $data_are_here | dumb_program?
वॉनब्रांड

1
यह केवल एक इनपुट फ़ाइल का समर्थन करेगा और स्टड से सभी प्रोग्राम नहीं पढ़ेगा।
Highsciguy

जवाबों:


55

एक नामित पाइप का उपयोग करें । चित्रण के माध्यम से:

mkfifo fifo
echo -e "hello world\nnext line\nline 3" > fifo

-eगूंज बताता है ठीक से न्यू लाइन से बच व्याख्या करने के लिए ( \n)। यह ब्लॉक करेगा, यानी, आपका शेल तब तक लटका रहेगा जब तक कि पाइप से कुछ डेटा नहीं पढ़ता।

एक और खोल कहीं और एक ही निर्देशिका में खोलें:

cat fifo

आप गूंज को पढ़ेंगे, जो अन्य शेल जारी करेगी। यद्यपि पाइप डिस्क पर फ़ाइल नोड के रूप में मौजूद है, जो डेटा इसके माध्यम से गुजरता है वह नहीं करता है; यह सब स्मृति में होता है। आप &ईको बैकग्राउंड ( ) कर सकते हैं ।

पाइप में 64k बफर (लाइनक्स पर) है और, सॉकेट की तरह, लेखक को पूर्ण होने पर ब्लॉक करेगा, इसलिए जब तक आप समय से पहले लेखक को नहीं मारते, तब तक आप डेटा नहीं खोएंगे।


ठीक है, धन्यवाद, यह दो नामित पाइप और wdiff के साथ भी काम करता है। लेकिन मैंने यह समझने के लिए सोचा कि बफर के रूप में पाइप के लिए एक निश्चित (छोटी) स्मृति उपलब्ध है। यदि मैं बफर आकार से अधिक हो तो क्या होगा?
11

मैंने उस मुद्दे के बारे में एक अंतिम पैराग्राफ जोड़ा।
गोल्डीलॉक्स

3
/tmpएक tmpfsफाइल सिस्टम का उपयोग करने के लिए सबसे डिस्ट्रो में कॉन्फ़िगर किया गया है जो रैम में है। जब आप एक फ़ाइल लिखते हैं तो /tmpयह सीधे आपके RAM में जाती है जो अर्ध-लचीला फ़ाइलों के लिए एक अच्छा उत्तर है, जिन्हें जल्दी से एक्सेस करना होगा और कई बार फिर से लिखना होगा।

129

बैश में, आप command1 <( command0 )रीडायरेक्ट सिंटैक्स का उपयोग कर सकते हैं , जो कि स्टडआउट को रीडायरेक्ट करता है command0और इसे पास command1करता है जो कमांड-लाइन तर्क के रूप में फ़ाइल नाम लेता है। इसे प्रक्रिया प्रतिस्थापन कहते हैं

कुछ प्रोग्राम जो फ़ाइल नाम कमांड-लाइन तर्कों को लेते हैं, वास्तव में एक वास्तविक यादृच्छिक-एक्सेस फ़ाइल की आवश्यकता होती है, इसलिए यह तकनीक उन लोगों के लिए काम नहीं करेगी। हालाँकि, यह ठीक काम करता है wdiff:

user@host:/path$ wdiff <( echo hello; echo hello1 ) <( echo hello; echo hello2 )
hello
[-hello1-]
{+hello2+}

पृष्ठभूमि में, यह एक FIFO बनाता है, FIFO के अंदर कमांड को पाइप करता है <( ), और FIFO के फाइल डिस्क्रिप्टर को एक तर्क के रूप में पास करता है। यह देखने के लिए कि क्या चल रहा है, इसके साथ echoतर्क का उपयोग करने के लिए इसके साथ कुछ भी किए बिना प्रिंट करने का प्रयास करें :

user@host:/path$ echo <( echo hello )
/dev/fd/63

नामित पाइप बनाना अधिक लचीला है (यदि आप कई प्रक्रियाओं का उपयोग करके जटिल पुनर्निर्देशन तर्क लिखना चाहते हैं), लेकिन कई उद्देश्यों के लिए यह पर्याप्त है, और स्पष्ट रूप से उपयोग करना आसान है।

>( )जब आप इसे आउटपुट के रूप में उपयोग करना चाहते हैं, तो इसके लिए वाक्य रचना भी है

$ someprogram --logfile >( gzip > out.log.gz )

संबंधित तकनीकों के लिए बैश पुनर्निर्देशन धोखा पत्र भी देखें ।


यह KSH में समर्थित नहीं है
chanchal1987

5
ksh ने इसका आविष्कार किया। आप ksh के एक प्रकार का उपयोग कर रहे हैं जो इसका समर्थन नहीं करता है
नील मैकगिनन

2
कुछ प्रोग्राम जो फ़ाइल नाम कमांड-लाइन तर्कों को लेते हैं, वास्तव में एक वास्तविक यादृच्छिक-एक्सेस फ़ाइल की आवश्यकता होती है, इसलिए यह तकनीक उन लोगों के लिए काम नहीं करेगी। आप इन मामलों में क्या करते हैं। उदाहरण के लिए ssh -F <(vagrant ssh-config) defaultवास्तव में अच्छा होगा, लेकिन अफसोस।
सुकिमा

10

wdiff एक विशेष मामला है, जिसके लिए 2 फ़ाइल नाम तर्क की आवश्यकता होती है, लेकिन सभी आदेशों के लिए जिन्हें केवल 1 तर्क की आवश्यकता होती है और जो कुछ भी लेने के लिए हठ करते हैं, लेकिन फ़ाइल नाम तर्क, 2 विकल्प हैं:

  • फ़ाइल नाम '-' (अर्थात, एक ऋण चिह्न) उस समय के लगभग 1/2 कार्य करता है। यह विचाराधीन कमांड पर निर्भर करता है और क्या कमांड का डेवलपर उस मामले में फंस जाता है और इसे अपेक्षित रूप से संभालता है। जैसे

    $> एलएस | बिल्ली -

  • एक psuedo फ़ाइल है जिसका नाम / dev / stdin है जो linux में मौजूद है और इसका उपयोग किया जा सकता है एक फ़ाइलनाम को एक कमांड द्वारा पूरी तरह से आवश्यक है। यह काम करने की अधिक संभावना है क्योंकि इसे कमांड से किसी विशेष फ़ाइलनाम हैंडलिंग की आवश्यकता नहीं है। यदि कोई फेनो काम करता है, या बैश प्रक्रिया प्रतिस्थापन विधि काम करती है तो यह भी काम करना चाहिए और शेल विशिष्ट नहीं है। जैसे

    $> एलएस | कैट / देव / स्टडिन


1
कम और खुलता है जैसे / dev / stdin बजाय / dev / fd / NUM :-)
eel ghEEz
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.