किसी फ़ाइल में एसटीडीईआरआर को रीडायरेक्ट कैसे करें

पृष्ठभूमि में चलाने के लिए कमांड डालने के लिए नोहुप का उपयोग करते समय कुछ सामग्री टर्मिनल में दिखाई देती है ।

cp: error reading ‘/mnt/tt/file.txt’: Input/output errorcp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

मैं उस सामग्री को एक फ़ाइल में सहेजना चाहता हूं ।

वहाँ रहे हैं दो मुख्य उत्पादन धाराओं में Linux (और अन्य ओएसएस), मानक आउटपुट (stdout) और मानक त्रुटि (stderr). त्रुटि संदेश, जैसे आप दिखाते हैं, मानक त्रुटि पर मुद्रित होते हैं । क्लासिक पुनर्निर्देशन ऑपरेटर (command > file) केवल मानक आउटपुट को रीडायरेक्ट करता है, इसलिए टर्मिनल पर मानक त्रुटि अभी भी दिखाई जाती है । एसटीडीईआरआर को भी रीडायरेक्ट करने के लिए, आपके पास कुछ विकल्प हैं:

  1. एक फ़ाइल में स्टडआउट को रीडायरेक्ट करें और दूसरी फ़ाइल में स्टडरर:

    command > out 2>error
  2. एक फ़ाइल में रीडायरेक्ट करें (>out), और फिर एसटीडीईआरआर को स्टडआउट पर रीडायरेक्ट करें (2>&1):

    command >out 2>&1
  3. दोनों को एक फ़ाइल पर पुनर्निर्देशित करें (यह सभी गोले द्वारा समर्थित नहीं है, bash और zsh उदाहरण के लिए इसका समर्थन करें, लेकिन sh और ksh नहीं):

    command &> out

विभिन्न नियंत्रण और पुनर्निर्देशन ऑपरेटरों पर अधिक जानकारी के लिए, देखें यहाँ.

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

पुनर्निर्देशन के पीछे मूल सिद्धांत यह है कि शेल द्वारा उत्पन्न एक प्रक्रिया (यह मानते हुए कि यह एक बाहरी कमांड है और शेल बिल्ट-इन नहीं है) के माध्यम से बनाई गई है fork() और execve() syscalls, और इससे पहले कि होता है एक और syscall dup2() पहले आवश्यक रीडायरेक्ट करता है execve() होता है । उस अर्थ में, पुनर्निर्देशन मूल शेल से विरासत में मिले हैं । द m&>n और m>n.txt प्रदर्शन करने के तरीके पर खोल को सूचित करें open() और dup2() syscall (यह भी देखें इनपुट पुनर्निर्देशन कैसे काम करता है, पुनर्निर्देशन और पाइप में क्या अंतर है, तथा आउटपुट पुनर्निर्देशन में वास्तव में क्या मतलब है )

खोल redirections

सबसे विशिष्ट, के माध्यम से है 2> में बॉर्न जैसे गोले, जैसे कि dash (जो सिमलिंक किया गया है /bin/sh) तथा bash; पहला डिफ़ॉल्ट और पॉज़िक्स-अनुरूप शेल है और दूसरा वह है जो अधिकांश उपयोगकर्ता इंटरैक्टिव सत्र के लिए उपयोग करते हैं । वे वाक्यविन्यास और सुविधाओं में भिन्न होते हैं, लेकिन सौभाग्य से हमारे लिए त्रुटि स्ट्रीम पुनर्निर्देशन समान काम करता है (सिवाय &> गैर मानक एक) । सीएसएच और उसके डेरिवेटिव के मामले में, एसटीडीईआरआर पुनर्निर्देशन वहां काफी काम नहीं करता है ।

चलो वापस आते हैं 2> भाग। नोटिस करने के लिए दो प्रमुख बातें: > पुनर्निर्देशन ऑपरेटर का मतलब है, जहां हम एक फ़ाइल खोलते हैं और 2 पूर्णांक एसटीडीईआरआर फ़ाइल डिस्क्रिप्टर के लिए खड़ा है; वास्तव में यह ठीक है कि शेल भाषा के लिए पॉज़िक्स मानक पुनर्निर्देशन को कैसे परिभाषित करता है धारा 2.7:

[n]redir-op word

सरल के लिए > पुनर्निर्देशन, को 1 पूर्णांक के लिए निहित है stdout, यानी echo Hello World > /dev/null जैसा ही है echo Hello World 1>/dev/null. ध्यान दें, कि पूर्णांक या पुनर्निर्देशन ऑपरेटर को उद्धृत नहीं किया जा सकता है, अन्यथा शेल उन्हें इस तरह से नहीं पहचानता है, और इसके बजाय पाठ के शाब्दिक स्ट्रिंग के रूप में व्यवहार करता है । रिक्ति के लिए, यह महत्वपूर्ण है कि पूर्णांक पुनर्निर्देशन ऑपरेटर के ठीक बगल में है, लेकिन फ़ाइल या तो पुनर्निर्देशन ऑपरेटर के बगल में हो सकती है या नहीं, अर्थात command 2>/dev/null और command 2> /dev/null बस ठीक काम करेगा।

शेल में विशिष्ट कमांड के लिए कुछ सरलीकृत सिंटैक्स होगा

 command [arg1] [arg2]  2> /dev/null

यहां चाल यह है कि पुनर्निर्देशन कहीं भी दिखाई दे सकता है । वह दोनों है 2> command [arg1] और command 2> [arg1] मान्य हैं । ध्यान दें कि के लिए bash खोल, वहाँ मौजूद है &> एक ही समय में स्टडआउट और स्टडर स्ट्रीम दोनों को रीडायरेक्ट करने का तरीका, लेकिन फिर से - यह बैश विशिष्ट है और यदि आप स्क्रिप्ट की पोर्टेबिलिटी के लिए प्रयास कर रहे हैं, तो यह काम नहीं कर सकता है । यह भी देखें Ubuntu विकी और >>और 2 और 1 में क्या अंतर है.

नोट:> पुनर्निर्देशन ऑपरेटर truncates एक फ़ाइल और इसे अधिलेखित करता है, अगर फ़ाइल मौजूद है । द 2>> लिए इस्तेमाल किया जा सकता appending stderr फाइल करने के लिए ।

यदि आप देख सकते हैं, > एक एकल आदेश के लिए है । स्क्रिप्ट के लिए, हम पूरी स्क्रिप्ट की एसटीडीईआरआर स्ट्रीम को बाहर से रीडायरेक्ट कर सकते हैं myscript.sh 2> /dev/null या हम का उपयोग कर सकते हैं exec में निर्मित. अंतर्निहित निष्पादन में पूरे शेल सत्र के लिए स्ट्रीम को फिर से चालू करने की शक्ति है, इसलिए बोलने के लिए, चाहे अंतःक्रियात्मक रूप से या स्क्रिप्ट के माध्यम से । कुछ ऐसा

#!/bin/shexec 2> ./my_log_file.txtstat /etc/non_existing_file

इस उदाहरण में, लॉग फ़ाइल को दिखाना चाहिए stat: cannot stat '/etc/non_existing_file': No such file or directory.

फिर भी एक और तरीका कार्यों के माध्यम से है । के रूप में सिंड्रेला उनके उत्तर में उल्लेख किया गया है, हम पहले से ही संलग्न पुनर्निर्देशन के साथ फ़ंक्शन घोषणा लिख सकते हैं, अर्थात

some_function(){    command1    command2} 2> my_log_file.txt

विशेष रूप से एसटीडीईआरआर को लिखने वाले आदेश

आदेश जैसे time और strace डिफ़ॉल्ट रूप से एसटीडीईआरआर को अपना आउटपुट लिखें । के मामले में time कमांड, एकमात्र व्यवहार्य विकल्प पूरे कमांड के आउटपुट को पुनर्निर्देशित करना है, अर्थात

time echo foo 2>&1 > file.txt

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

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

अन्य आदेश, जैसे strace या dialog एसटीडीईआरआर को पुनर्निर्देशित करने के साधन प्रदान करें । strace है -o <filename.txt> विकल्प जो फ़ाइल नाम निर्दिष्ट करने की अनुमति देता है जहां आउटपुट लिखा जाना चाहिए । प्रत्येक उपप्रकार के लिए एक टेक्स्टफाइल लिखने का विकल्प भी है strace देखता है । द dialog कमांड टेक्स्ट यूजर इंटरफेस को स्टडआउट पर लिखता है लेकिन स्टडरर को आउटपुट करता है, इसलिए इसके आउटपुट को वेरिएबल में सेव करें (क्योंकि var=$(...) और पाइपलाइन केवल एसटीडीईआरआर प्राप्त करते हैं) हमें फ़ाइल डिस्क्रिप्टर को स्वैप करने की आवश्यकता है

result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);

लेकिन इसके अतिरिक्त, वहाँ है --output-fd ध्वज, जिसका हम भी उपयोग कर सकते हैं । नामित पाइप की विधि भी है । मैं लिंक की गई पोस्ट को पढ़ने की सलाह देता हूं dialog क्या हो रहा है के गहन विवरण के लिए आदेश ।

@ टेरडन यह एक अधिक विशिष्ट प्रश्न है, और यह अधिक विशिष्ट प्रश्न के लिए गूगल खोज में सही रूप से दिखाई देता है, जो एक अच्छी बात है ।

@ हाँ, और यह दिखाई देगा, यह नहीं बदलेगा । लेकिन किसी भी नए उत्तर को अधिक सामान्य प्रश्न पर जाना चाहिए ।