शेल के नियंत्रण और पुनर्निर्देशन ऑपरेटर क्या हैं?


245

मैं अक्सर ऑनलाइन ट्यूटोरियल देखता हूं जो विभिन्न कमांड्स को विभिन्न प्रतीकों से जोड़ते हैं। उदाहरण के लिए:

command1 |  command2
command1 &  command2
command1 || command2    
command1 && command2

दूसरों को फ़ाइलों से कमांड कनेक्ट करना प्रतीत होता है:

command1  > file1
command1  >> file1

ये चीजें क्या हैं? वे क्या कहलाते हैं? वो क्या करते हैं? क्या उनमें से कुछ और हैं?


इस प्रश्न के बारे में मेटा थ्रेड।

जवाबों:


340

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

A. कंट्रोल ऑपरेटर्स

शेल कमांड भाषा में, एक टोकन जो एक नियंत्रण फ़ंक्शन करता है।
यह निम्नलिखित प्रतीकों में से एक है:

&   &&   (   )   ;   ;;   <newline>   |   ||

और |&बाश में।

एक !है नहीं एक नियंत्रण ऑपरेटर लेकिन एक आरक्षित शब्द । यह एक तार्किक नहीं [निषेध संचालक] अंकगणितीय अभिव्यक्तियों के अंदर और परीक्षण निर्माणों के अंदर (जबकि अभी भी अंतरिक्ष परिसीमन की आवश्यकता है) बन जाता है।

A.1 सूची टर्मिनेटर

  • ; : पहले के परिणाम के बावजूद, एक के बाद एक कमांड चलाएंगे।

    command1 ; command2

    पहले command1चलाया जाता है, अग्रभूमि में, और एक बार जब यह समाप्त हो जाता है, command2तो चलाया जाएगा।

    एक नई पंक्ति जो एक स्ट्रिंग शाब्दिक या कुछ कीवर्ड के बाद अर्धविराम ऑपरेटर के बराबर नहीं है । की एक सूची ;सीमांकित सरल आदेशों अभी भी एक है सूची - खोल के पार्सर में के रूप में अभी भी सरल आदेशों एक का पालन में पढ़ने के लिए जारी रखना चाहिए ;या सूचियों की सूची -, निष्पादित करने से पहले सीमांकित साधारण आदेश जबकि एक नई पंक्ति एक पूरे आदेश सूची परिसीमित कर सकते हैं। अंतर सूक्ष्म है, लेकिन जटिल है: शेल को एक नई रेखा के बाद डेटा में पढ़ने के लिए कोई पिछली अनिवार्यता नहीं है, न्यूलाइन एक बिंदु को चिह्नित करता है जहां शेल उस सरल कमांड का मूल्यांकन करना शुरू कर सकता है जो पहले से ही पढ़ा गया है, जबकि एक ;अर्ध-कोलन करता है नहीं।

  • & : यह पृष्ठभूमि में एक कमांड चलाएगा, जिससे आप एक ही शेल में काम करना जारी रख सकेंगे।

     command1 & command2

    यहां, command1पृष्ठभूमि में लॉन्च किया गया है और बाहर निकलने के command2लिए इंतजार किए बिना, तुरंत अग्रभूमि में चलना शुरू होता है command1

    command1वैकल्पिक होने के बाद एक नई पंक्ति ।

A.2 तार्किक संचालक

  • && : निर्माण और सूचियों के लिए उपयोग किया जाता है, यह आपको केवल एक कमांड चलाने की अनुमति देता है यदि कोई अन्य सफलतापूर्वक बाहर निकलता है।

     command1 && command2

    यहां, समाप्त command2होने के बाद चलेगा command1और केवल तभी command1सफल हुआ था (यदि इसका निकास कोड 0 था)। दोनों कमांड अग्रभूमि में चलाए जाते हैं।

    यह कमांड भी लिखी जा सकती है

    if command1
    then command2
    else false
    fi

    या बस if command1; then command2; fiअगर वापसी की स्थिति की अनदेखी की जाती है।

  • || : या सूचियों का निर्माण करने के लिए उपयोग किया जाता है, यह आपको केवल एक कमांड चलाने की अनुमति देता है यदि कोई अन्य असफल रूप से बाहर निकलता है।

     command1 || command2

    यहां, command2केवल तभी चलेगा जब command1असफल (यदि यह 0 से बाहर निकलने की स्थिति में लौटा हो)। दोनों कमांड अग्रभूमि में चलाए जाते हैं।

    यह कमांड भी लिखी जा सकती है

    if command1
    then true
    else command2
    fi

    या छोटे तरीके से if ! command1; then command2; fi

    ध्यान दें कि &&और ||बाएं-सहयोगी हैं; शेल तार्किक ऑपरेटरों की वरीयता देखें &&, || अधिक जानकारी के लिए।

  • !: यह एक आरक्षित शब्द है जो "नहीं" ऑपरेटर (लेकिन परिसीमन होना चाहिए) के रूप में कार्य करता है, जिसका उपयोग कमांड की वापसी स्थिति को नकारने के लिए किया जाता है - वापसी 0 यदि कमांड नॉनजरो स्थिति देता है, तो 1 लौटाता है यदि यह स्थिति 0 लौटाता है। testउपयोगिता के लिए भी तार्किक नहीं ।

    ! command1
    
    [ ! a = a ]

    और अंकगणित अभिव्यक्तियों के अंदर एक सच्चा संचालक नहीं:

    $ echo $((!0)) $((!23))
    1 0

A.3 पाइप ऑपरेटर

  • |: पाइप ऑपरेटर, यह दूसरे के इनपुट के रूप में एक कमांड के आउटपुट को पास करता है। पाइप ऑपरेटर से निर्मित एक कमांड को पाइप लाइन कहा जाता है ।

     command1 | command2

    द्वारा मुद्रित किसी भी आउटपुट command1को इनपुट के रूप में पारित किया जाता है command2

  • |&: यह 2>&1 |बैश और zsh में एक आशुलिपि है । यह मानक आउटपुट और एक कमांड के मानक त्रुटि दोनों को इनपुट के रूप में पारित करता है।

    command1 |& command2

A.4 अन्य सूची विराम चिह्न

;;केवल केस स्टेटमेंट के अंत को चिह्नित करने के लिए उपयोग किया जाता है । Ksh, bash और zsh भी ;&अगले मामले में गिरने के लिए समर्थन करते हैं और ;;&(ATT ksh में नहीं) अन्य मामलों में जाने और परीक्षण करने के लिए।

(और समूह आदेशों के) लिए उपयोग किया जाता है और उन्हें एक उपधारा में लॉन्च करता है। और समूह के आदेश भी, लेकिन उन्हें एक उपधारा में लॉन्च न करें। शेल सिंटैक्स में विभिन्न प्रकार के कोष्ठक, कोष्ठक और ब्रेसिज़ की चर्चा के लिए इस उत्तर को देखें ।{}

B. पुनर्निर्देशन संचालक

पुनर्निर्देशन संचालक

शेल कमांड भाषा में, एक टोकन जो पुनर्निर्देशन फ़ंक्शन करता है। यह निम्नलिखित प्रतीकों में से एक है:

<     >     >|     <<     >>     <&     >&     <<-     <>

ये आपको अपने कमांड के इनपुट और आउटपुट को नियंत्रित करने की अनुमति देते हैं। वे एक साधारण आदेश के भीतर कहीं भी प्रकट हो सकते हैं या एक आदेश का पालन कर सकते हैं। पुनर्निर्देशन वे दिखाई देने वाले क्रम में संसाधित होते हैं, बाएं से दाएं।

  • < : एक कमांड में इनपुट देता है।

    command < file.txt

    उपरोक्त commandकी सामग्री पर अमल करेगा file.txt

  • <>: ऊपर के समान, लेकिन फ़ाइल केवल-पढ़ने के बजाय रीड + राइट मोड में खुली है :

    command <> file.txt

    यदि फ़ाइल मौजूद नहीं है, तो इसे बनाया जाएगा।

    उस ऑपरेटर का उपयोग शायद ही कभी किया जाता है क्योंकि कमांड आमतौर पर केवल उनके स्टड से पढ़ते हैं , हालांकि यह कई विशिष्ट स्थितियों में काम आ सकता है

  • > : एक फ़ाइल में एक कमांड के आउटपुट को निर्देशित करता है।

    command > out.txt

    ऊपर के commandरूप में के उत्पादन को बचाएगा out.txt। यदि फ़ाइल मौजूद है, तो इसकी सामग्री को अधिलेखित कर दिया जाएगा और यदि यह मौजूद नहीं है तो इसे बनाया जाएगा।

    यह ऑपरेटर अक्सर यह चुनने के लिए भी उपयोग किया जाता है कि क्या मानक त्रुटि या मानक आउटपुट पर कुछ मुद्रित किया जाना चाहिए :

    command >out.txt 2>error.txt

    ऊपर के उदाहरण में, >मानक आउटपुट को रीडायरेक्ट करेगा और 2>मानक त्रुटि को पुनर्निर्देशित करेगा । आउटपुट का उपयोग करके पुनर्निर्देशित भी किया जा सकता है 1>, लेकिन चूंकि यह डिफ़ॉल्ट है, 1आमतौर पर छोड़ा जाता है और इसे बस के रूप में लिखा जाता है >

    इसलिए, अपने आउटपुट को commandचालू करने file.txtऔर सहेजने के लिए out.txtऔर आपके द्वारा कोई भी त्रुटि संदेश error.txtचलाने के लिए:

    command < file.txt > out.txt 2> error.txt
  • >|: के रूप में ही करता है >, लेकिन लक्ष्य को अधिलेखित कर देगा, भले ही शेल ओवरराइटिंग (साथ set -Cया set -o noclobber) से इनकार करने के लिए कॉन्फ़िगर किया गया हो ।

    command >| out.txt

    यदि out.txtमौजूद है, तो आउटपुट commandइसकी सामग्री को बदल देगा। यदि यह मौजूद नहीं है तो इसे बनाया जाएगा।

  • >>: वही करता है >, सिवाय इसके कि यदि लक्ष्य फ़ाइल मौजूद है, तो नया डेटा जोड़ा जाता है।

    command >> out.txt

    यदि out.txtमौजूद है, तो commandउसमें जो कुछ भी पहले से है, उसका आउटपुट उसमें जोड़ा जाएगा। यदि यह मौजूद नहीं है तो इसे बनाया जाएगा।

  • &>, >&, >>&और &>>: (गैर मानक)। क्रमशः मानक त्रुटि और मानक आउटपुट, को बदलना या जोड़ना दोनों को रीडायरेक्ट करें।

    command &> out.txt

    मानक त्रुटि और मानक आउटपुट दोनों commandको out.txtइसकी सामग्री को अधिलेखित करने या इसे मौजूद न करने पर बनाने से बचाया जाएगा ।

    command &>> out.txt

    ऊपर के रूप में, सिवाय इसके कि यदि out.txtमौजूद है, तो आउटपुट और त्रुटि commandको इसके साथ जोड़ा जाएगा।

    &>संस्करण में निकलती है bash, जबकि, >&संस्करण csh (दशक पहले) से आता है। वे दोनों अन्य POSIX शेल ऑपरेटरों के साथ संघर्ष करते हैं और उन्हें पोर्टेबल shस्क्रिप्ट में उपयोग नहीं किया जाना चाहिए ।

  • <<: यहां एक दस्तावेज। इसका उपयोग अक्सर बहु-पंक्ति स्ट्रिंग्स को प्रिंट करने के लिए किया जाता है।

     command << WORD
         Text
     WORD

    यहां, commandसब कुछ तब तक ले जाएगा जब तक कि अगली घटना का पता न चल जाए WORD, Textउदाहरण के लिए, इनपुट के रूप में। जबकि WORDअक्सर EoFया इसके रूपांतर होते हैं, यह आपके द्वारा पसंद किए जाने वाले किसी भी अल्फ़ान्यूमेरिक (और न केवल) स्ट्रिंग हो सकता है। जब WORDउद्धृत किया जाता है, तो यहां दस्तावेज़ में पाठ का शाब्दिक रूप से व्यवहार किया जाता है और कोई विस्तार नहीं किया जाता है (उदाहरण के लिए चर पर)। यदि यह निर्विवाद है, तो चर का विस्तार किया जाएगा। अधिक जानकारी के लिए, बैश मैनुअल देखें ।

    यदि आप command << WORD ... WORDकिसी अन्य कमांड या कमांड में सीधे आउटपुट को पाइप करना चाहते हैं , तो आपको पाइप को उसी लाइन पर रखना होगा << WORD, जैसा कि आप समाप्त वर्ड के बाद या लाइन पर निम्नलिखित के बाद नहीं डाल सकते। उदाहरण के लिए:

     command << WORD | command2 | command3...
         Text
     WORD
  • <<<: यहाँ तार, यहाँ दस्तावेजों के समान है, लेकिन एक लाइन के लिए इरादा है। ये केवल यूनिक्स पोर्ट या आरसी (जहां इसकी उत्पत्ति हुई) में मौजूद हैं, zsh, ksh, यश और बैश के कुछ कार्यान्वयन।

    command <<< WORD

    जो कुछ दिया गया है WORDवह विस्तारित है और इसका मान इनपुट के रूप में दिया गया है command। यह अक्सर कमांड के इनपुट के रूप में चर की सामग्री को पास करने के लिए उपयोग किया जाता है। उदाहरण के लिए:

     $ foo="bar"
     $ sed 's/a/A/' <<< "$foo"
     bAr
     # as a short-cut for the standard:
     $ printf '%s\n' "$foo" | sed 's/a/A/'
     bAr
     # or
     sed 's/a/A/' << EOF
     $foo
     EOF

कुछ अन्य ऑपरेटर ( >&-, x>&y x<&y) फ़ाइल डिस्क्रिप्टर को बंद या डुप्लिकेट करने के लिए उपयोग किया जा सकता है। उन पर जानकारी के लिए कृपया अपने खोल मैनुअल के प्रासंगिक अनुभाग (देखें यहाँ उदाहरण के लिए पार्टी के लिए)।

यह केवल बॉर्न जैसे गोले के सबसे आम ऑपरेटरों को कवर करता है। कुछ गोले अपने स्वयं के कुछ अतिरिक्त पुनर्निर्देशन ऑपरेटर हैं।

Ksh, bash और zsh के भी कंस्ट्रक्शन हैं <(…), >(…)और =(…)( zshकेवल बाद वाले वाले )। ये पुनर्निर्देशन नहीं हैं, लेकिन प्रतिस्थापन की प्रक्रिया है


2
यह संभवतः सार्थक होगा कि सभी गोले समान नहीं हैं, और विशेष रूप से बैश-विशिष्ट विशेषताओं को उजागर करते हैं।
ग्रेग हेविल जिल

1
@GregHewgill हाँ, मैंने यह कहकर इसे समाप्त कर दिया कि मैं सम्मान के साथ चर्चा कर रहा हूं bash। यह विभिन्न "क्या इस अजीब बात करते हैं" सवालों को बंद करने के लिए एक विहित क्यू एंड ए के रूप में तैयार किया जा रहा है और उनमें से अधिकांश बैश के उपयोगकर्ताओं से हैं। मैं उम्मीद कर रहा हूं कि कोई अन्य व्यक्ति गैर-बैश शेल के लिए पिच करेगा और जवाब देगा, लेकिन बैश-विशिष्ट लोगों को उजागर करना बहुत मायने रखता है। मुझे जाँच करनी होगी, मुझे नहीं पता कि वे मेरे सिर के ऊपर से हैं।
terdon

&>, >>>और <<<सभी गैर-पॉज़िक्स हैं जैसा कि यहाँ-डॉक्टर के नाम में न केवल गैर-अल्फ़ान्यूम वर्णों का संदर्भ है । यह जवाब भी बहुत कम चर्चा करता है कि वे कैसे काम करते हैं - उदाहरण के लिए, एक साधारण कमांड और एक कमांड के बारे में बात करना बेकार की तुलना में लगभग बदतर है, यह बताए बिना कि ये क्या हैं और शेल कैसे तय करता है।
मोकेसर

@mikeserv धन्यवाद। वे हालांकि बैश और zsh पर काम करते हैं। मैं नहीं जानता कि क्या, अगर कुछ भी, वास्तव में उस सूची में बैश-विशिष्ट है। मुझे इसके माध्यम से जाना चाहिए और प्रत्येक कार्य के गोले को जोड़ना होगा लेकिन इसमें पहले पता लगाना शामिल होगा।
terdon

1
@ Arc676 नहीं, वे सही या गलत का मूल्यांकन नहीं करते हैं, यह पूरी तरह से अलग संदर्भ है। इसका मतलब यह है कि गैर-0 का एक निकास मूल्य एक समस्या (नहीं false) को इंगित करता है और 0 का एक निकास कोड सफलता (नहीं true) को इंगित करता है । यह हमेशा तरीका रहा है और काफी मानक है। एक गैर-0 निकास कोड मेरे द्वारा ज्ञात प्रत्येक वातावरण में एक त्रुटि दर्शाता है।
terdon

60

'>' के बारे में चेतावनी

यूनिक्स शुरुआती जिन्होंने अभी-अभी I / O पुनर्निर्देशन ( <और >) के बारे में सीखा है , जैसे अक्सर चीजों की कोशिश करते हैं

कमांडinput_file > the_same_file

या

कमांड ... < फ़ाइल      > the_same_file

या, लगभग बराबर,

बिल्ली फ़ाइल | कमांड ...> the_same_file

( grep, sed, cut, sort, और spellआज्ञाओं है कि लोगों को इस तरह के निर्माणों में उपयोग करने के लिए परीक्षा रहे हैं के उदाहरण हैं।) उपयोगकर्ता है कि इन स्थितियों फ़ाइल में परिणाम खाली होता जा रहा की खोज कर हैरान हैं।

एक अति सूक्ष्म अंतर जो अन्य उत्तर में उल्लिखित नहीं लगता है, उसे बैश (1) के पुनर्निर्देशन अनुभाग के पहले वाक्य में गुप्त पाया जा सकता है :

एक कमांड निष्पादित होने से पहले, इसके इनपुट और आउटपुट को शेल द्वारा व्याख्या किए गए एक विशेष नोटेशन का उपयोग करके पुनर्निर्देशित किया जा सकता है ।

पहले पांच शब्दों को बोल्ड, इटैलिक, अंडरलाइन, बड़ा, ब्लिंकिंग, कलर्ड रेड और एक लाल त्रिकोण में विस्मयादिबोधक चिह्नआइकन से चिह्नित किया जाना चाहिए , ताकि इस तथ्य पर जोर दिया जा सके कि शेल कमांड निष्पादित होने से पहले अनुरोध किए गए पुनर्निर्देशन (ओं) को करता है । और याद भी

आउटपुट का पुनर्निर्देशन फ़ाइल का कारण बनता है… लेखन के लिए खोला जाना…। यदि फ़ाइल मौजूद नहीं है तो इसे बनाया जाता है; यदि यह मौजूद है तो इसे शून्य आकार में काट दिया जाता है।

  1. तो, इस उदाहरण में:

    sort roster > roster

    शेल प्रोग्राम को चलाने rosterसे पहले, इसे लिखने के लिए फ़ाइल को खोलता है , इसे रौंदता है (यानी, अपनी सभी सामग्री को छोड़ देता है) sort। स्वाभाविक रूप से, डेटा को पुनर्प्राप्त करने के लिए कुछ भी नहीं किया जा सकता है।

  2. कोई भोलेपन से उम्मीद कर सकता है कि

    tr "[:upper:]" "[:lower:]" < poem > poem

    बेहतर हो सकता है। क्योंकि शेल बाएं से दाएं पुनर्निर्देशन को संभालता है, यह poemपढ़ने के लिए ( trमानक मानक के लिए ) खुलता है इससे पहले कि वह इसे लिखने के लिए (मानक आउटपुट के लिए) खोलता है। लेकिन यह मदद नहीं करता है। भले ही संचालन का यह क्रम दो फ़ाइल हैंडल देता है, लेकिन वे दोनों एक ही फ़ाइल को इंगित करते हैं। जब शेल पढ़ने के लिए फ़ाइल को खोलता है, तो सामग्री अभी भी वहां है, लेकिन वे अभी भी प्रोग्राम निष्पादित होने से पहले क्लोब किए जाते हैं। 

तो, इसके बारे में क्या करना है?

समाधान में शामिल हैं:

  • जांचें कि क्या आप जो प्रोग्राम चला रहे हैं, उसकी अपनी आंतरिक, आंतरिक क्षमता है, यह निर्दिष्ट करने के लिए कि आउटपुट कहां जाता है। यह अक्सर एक -o(या --output=) टोकन द्वारा इंगित किया जाता है । विशेष रूप से,

    sort roster -o roster

    के बराबर है

    sort roster > roster

    को छोड़कर, पहले मामले में, sortप्रोग्राम आउटपुट फ़ाइल खोलता है। और यह काफी स्मार्ट है कि आउटपुट फाइल को तब तक न खोलें, जब तक कि यह सभी इनपुट फाइल (ओं) को नहीं पढ़ लेता।

    इसी प्रकार, कम से कम कुछ संस्करणों sedएक है -i(संपादन मैं n जगह) विकल्प है कि उत्पादन वापस इनपुट फ़ाइल के लिए बाहर लिखने के लिए इस्तेमाल किया जा सकता (फिर से, के बाद सभी इनपुट पढ़ा गया है)। जैसे संपादकों ed/ ex, emacs, pico, और vi/ vim उपयोगकर्ता एक पाठ फ़ाइल को संपादित करने और मूल फ़ाइल में संपादित टेक्स्ट को बचाने के लिए अनुमति देते हैं। ध्यान दें कि ed(कम से कम) का उपयोग गैर-अंतःक्रियात्मक रूप से किया जा सकता है।

    • viएक संबंधित सुविधा है। यदि आप टाइप करते हैं , तो यह एडिट बफर की सामग्री को आउट टू आउट , आउटपुट को पढ़ने, और बफर में डालने (मूल सामग्री को बदलने) को लिख देगा ।:%!commandEntercommand
  • सामान्य लेकिन प्रभावी:

    कमांडinput_file > temp_file   && mv temp_file  input_file

    इसका दोष यह है कि, यदि input_fileकोई लिंक है, तो वह (संभवतः) एक अलग फ़ाइल द्वारा प्रतिस्थापित किया जाएगा। साथ ही, नई फ़ाइल आपके पास डिफ़ॉल्ट सुरक्षा के साथ होगी। विशेष रूप से, यह जोखिम वहन करता है कि फ़ाइल विश्व-पठनीय होगी, भले ही मूल input_fileन हो।

    बदलाव:

    • commandinput_file > temp_file && cp temp_file input_file && rm temp_file
      जो अभी भी (संभावित) temp_fileदुनिया को पढ़ने योग्य छोड़ देगा । और भी बेहतर:
    • cp input_file temp_file && commandtemp_file > input_file && rm temp_file
      ये फ़ाइल की लिंक स्थिति, स्वामी और मोड (सुरक्षा) को संरक्षित करते हैं, संभवतः I / O की दोगुनी लागत पर। (आपको विशेषताओं को संरक्षित करने के लिए इसे पसंद करने के लिए -aया उस -pपर एक विकल्प का उपयोग करने की आवश्यकता हो सकती है cp।)
    • commandinput_file > temp_file &&
      cp --attributes-only --preserve=all input_file temp_file &&
      mv temp_file input_file
      (केवल पठनीयता के लिए अलग-अलग लाइनों में टूटा हुआ) यह फ़ाइल के मोड को संरक्षित करता है (और, यदि आप रूट, स्वामी हैं), लेकिन यह आपके द्वारा स्वामित्व में है (यदि आप रूट नहीं हैं), और इसे नया बनाता है ( अलग फाइल।
  • यह ब्लॉग ("इन-प्लेस" फाइलों का संपादन) सुझाव और व्याख्या करता है

    {rm input_file   &&   कमांड …> input_file ; } < input_file

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

  • Moreutils पैकेज में एक कमांड होती है जिसे कहा जाता है sponge:

    कमांड ... input_file | स्पंज the_same_file

    अधिक जानकारी के लिए यह उत्तर देखें ।

यहाँ कुछ ऐसा है जो मेरे लिए एक पूर्ण आश्चर्य के रूप में आया है: वाक्यविन्यास कहता है :

[इन समाधानों में से अधिकांश] केवल पढ़ने के लिए फाइल सिस्टम है, जहां "रीड-ओनली" मतलब है कि आपके पर विफल हो जाएगा $HOME होगा लिखने योग्य हो, लेकिन /tmpहो जाएगा -केवल पढ़ने के लिए (डिफ़ॉल्ट रूप से)। उदाहरण के लिए, यदि आपके पास उबंटू है, और आपने रिकवरी कंसोल में बूट किया है, तो यह आमतौर पर मामला है। इसके अलावा, यहाँ-दस्तावेज़ ऑपरेटर <<<भी वहाँ काम नहीं करेगा, क्योंकि इसे पढ़ने / लिखने की आवश्यकता /tmpहै क्योंकि यह एक अस्थायी फ़ाइल को वहां भी लिख देगा। (cf. इस प्रश्न में 'डी आउटपुट' शामिल है )
strace

निम्नलिखित उस मामले में काम कर सकता है:

  • उन्नत उपयोगकर्ताओं के केवल के लिए: (जैसे, अपने आदेश के रूप में वहाँ इनपुट है उत्पादन डेटा की समान राशि प्राप्त होने की गारंटी है, तो sort, या tr बिना-d या -sविकल्प), तुम कोशिश कर सकते
    कमांड ... input_file | dd of = the_same_file conv = notrunc
    देखें इस सवाल का जवाब और इस उत्तर के ऊपर का एक विवरण सहित अधिक जानकारी के लिए, और विकल्प है कि काम करता है, तो अपने आदेश के रूप में वहाँ इनपुट है उत्पादन डेटा की समान राशि प्राप्त होने की गारंटी है या उससे कम (जैसे, grep, या cut)। इन उत्तरों में यह लाभ है कि उन्हें किसी भी खाली स्थान की आवश्यकता नहीं होती है (या उन्हें बहुत कम आवश्यकता होती है)। प्रपत्र के ऊपर दिए गए उत्तरों में स्पष्ट रूप से यह आवश्यक है कि सिस्टम के लिए पर्याप्त खाली जगह हो ताकि एक साथ संपूर्ण इनपुट (पुरानी) फ़ाइल और आउटपुट (नई) फ़ाइल को रखने में सक्षम हो; यह गैर-स्पष्ट रूप से अधिकांश अन्य समाधानों (जैसे, और ) के लिए भी सही है। अपवाद: शायद बहुत सारे खाली स्थान की आवश्यकता होगी, क्योंकिcommandinput_file > temp_file && …sed -ispongesort … | dd …sort किसी भी आउटपुट को लिखने से पहले उसके सभी इनपुट को पढ़ने की आवश्यकता है, और यह शायद सबसे अधिक बफर करता है यदि सभी डेटा एक अस्थायी फ़ाइल में नहीं।
  • केवल उन्नत उपयोगकर्ताओं के लिए:
    कमांड ... input_file 1 <> the_same_file
    ddउत्तर के बराबर हो सकता है , ऊपर। वाक्य रचना फ़ाइल वर्णनकर्ता पर नामित फ़ाइल को खोलता है दोनों इनपुट और आउटपुट के लिए , यह छोटा बिना - का एक संयोजन की तरह और । नोट: कुछ प्रोग्राम (जैसे, और ) इस परिदृश्य में चलने से इनकार कर सकते हैं क्योंकि वे यह पता लगा सकते हैं कि इनपुट और आउटपुट एक ही फाइल हैं। उपर्युक्त की चर्चा के लिए इस उत्तर को देखें , और एक स्क्रिप्ट जो इस उत्तर को काम करती है यदि आपका कमांड आउटपुट डेटा की समान मात्रा का उत्पादन करने की गारंटी देता है क्योंकि इसमें इनपुट या कम है । चेतावनी: मैंने पीटर की स्क्रिप्ट का परीक्षण नहीं किया है, इसलिए मैं इसके लिए प्रतिज्ञा नहीं करता हूं।n<> filen n<n>catgrep

तो, सवाल क्या था?

यह U & L पर एक लोकप्रिय विषय रहा है; इसे निम्नलिखित प्रश्नों में संबोधित किया गया है:

… और वह सुपर यूजर या उबंटू नहीं गिन रहा है। मैंने उपरोक्त प्रश्नों के उत्तर से लेकर इस उत्तर में बहुत सारी जानकारी शामिल की है, लेकिन सभी में नहीं। (यानी, अधिक जानकारी के लिए, ऊपर सूचीबद्ध प्रश्न और उनके उत्तर पढ़ें।)

PS मुझे उस ब्लॉग से कोई संबद्धता नहीं है जिसका मैंने उल्लेख किया है, ऊपर।


चूँकि यह सवाल सामने आता रहता है, मैंने सोचा कि मैं "विहित उत्तर" लिखने में अपना हाथ आज़माऊँगा। क्या मुझे इसे यहाँ पोस्ट करना चाहिए (और हो सकता है कि यह कुछ अन्य भारी-भरकम ट्रैफ़िक प्रश्नों में से लिंक हो), या क्या मुझे इसे उन सवालों में से एक पर स्थानांतरित करना चाहिए जो वास्तव में इस मुद्दे को उठाते हैं? इसके अलावा, क्या यह शायद एक ऐसी स्थिति है जहां सवालों का विलय किया जाना चाहिए?
स्कॉट

/ tmp एक निर्देशिका को उन अनुप्रयोगों के लिए उपलब्ध कराया जाता है जिन्हें अस्थायी फ़ाइलों को बनाने के लिए जगह की आवश्यकता होती है। अनुप्रयोगों को इस निर्देशिका में फ़ाइलें बनाने की अनुमति दी जाएगी, लेकिन यह नहीं मानेंगे कि ऐसी फाइलें आवेदन के इनवोकेशन के बीच संरक्षित हैं।
22

@mikeserv: हाँ, (1) मैं वाक्यविन्यास उद्धृत कर रहा हूँ, और (2) मैंने कहा कि मैं आश्चर्यचकित था। मैंने सोचा कि, अगर कुछ भी पढ़ा-लिखा होगा, तो यह होगा /tmp
स्कॉट

वैसे, @syntaxerror ने कहा कि यह दोगुना अजीब है क्योंकि मुझे लगता है कि dashउबंटू पर डिफ़ॉल्ट रिकवरी शेल होगा और यह न केवल एक <<<हेस्ट्रिंग को समझता है , बल्कि यह <<heredocuments के लिए अनाम पाइप भी प्राप्त करता है और इसके साथ गड़बड़ नहीं करता ${TMPDIR:-/tmp}है सब पर उद्देश्य। डेमो-दस्तावेज़ हैंडलिंग पर डेमो के लिए इसे या इसे देखें । इसके अलावा आउटपुट या कम चेतावनी की समान मात्रा क्यों ?
mikeserv

@mikeserv: खैर, dd … conv=notruncऔर 1<>उत्तर कभी आउटपुट फ़ाइल को छोटा नहीं करते हैं, इसलिए, यदि कमांड का आउटपुट इनपुट (जैसे grep) से कम है, तो फ़ाइल के अंत में मूल बायीं तरफ कुछ बाइट्स होंगे। और, यदि उत्पादन इनपुट से भी बड़ा है (जैसे, cat -n, nl, या (संभावित) grep -n), पुराने डेटा को अधिलेखित इससे पहले कि आप पढ़ा है की एक खतरा है।
स्कॉट

29

अधिक टिप्पणियों ;, पर &, (और)

  • ध्यान दें कि टेर्डन के उत्तर में कुछ कमांड शून्य हो सकती हैं। उदाहरण के लिए, आप कह सकते हैं

    command1 ;

    (नहीं के साथ command2)। इसके बराबर है

    command1

    (यानी, यह केवल command1अग्रभूमि में चलता है और इसके पूरा होने की प्रतीक्षा करता है। तुलनात्मक रूप से,

    command1 &

    (नहीं के साथ command2) command1पृष्ठभूमि में लॉन्च होगा और फिर तुरंत एक और शेल प्रॉम्प्ट जारी करेगा।

  • इसके विपरीत, command1 &&, command1 ||, और command1 |कोई मतलब नहीं है। यदि आप इनमें से एक टाइप करते हैं, तो शेल (शायद) यह मान लेगा कि कमांड दूसरी लाइन पर जारी है। यह द्वितीयक (निरंतरता) शेल प्रांप्ट प्रदर्शित करेगा, जो सामान्य रूप से सेट किया गया है >, और पढ़ता रहता है। एक शेल स्क्रिप्ट में, यह केवल अगली पंक्ति को पढ़ेगा और इसे पहले से पढ़ी गई चीज़ों के साथ जोड़ देगा। (खबरदार: यह वह नहीं हो सकता है जो आप करना चाहते हैं।)

    नोट: कुछ गोले के कुछ संस्करण ऐसी अपूर्ण कमांड को त्रुटियों के रूप में मान सकते हैं। ऐसे मामलों में (या, वास्तव में, किसी भी मामले में जहां आपके पास एक लंबी कमान है), आप \एक पंक्ति के अंत में एक पंक्ति के अंत में बैकस्लैश ( ) डाल सकते हैं ताकि दूसरी पंक्ति पर कमांड को पढ़ना जारी रखा जा सके:

    command1  &&  \
    command2

    या

    find starting-directory -mindepth 3 -maxdepth 5 -iname "*.some_extension" -type f \
                            -newer some_existing_file -user fred -readable -print
  • जैसा कि टेर्डन कहते हैं, (और )समूह आदेशों के लिए इस्तेमाल किया जा सकता है। उस चर्चा के लिए वे "वास्तव में प्रासंगिक नहीं हैं" बयान बहस का विषय है। टेर्डन के उत्तर में कुछ कमांड कमांड समूह हो सकते हैं । उदाहरण के लिए,

    ( command1 ; command2 )  &&  ( command3; command4 )

    क्या ये:

    • दौड़ें command1और इसके खत्म होने का इंतज़ार करें।
    • फिर, उस पहले आदेश को चलाने के परिणाम की परवाह किए बिना, दौड़ें command2और इसके समाप्त होने की प्रतीक्षा करें।
    • फिर, यदि command2सफल हुआ,

      • दौड़ें command3और इसके खत्म होने का इंतज़ार करें।
      • फिर, उस आदेश को चलाने के परिणाम की परवाह किए बिना, दौड़ें command4और इसके समाप्त होने की प्रतीक्षा करें।

      यदि command2विफल रहा है, तो कमांड लाइन को संसाधित करना बंद करें।

  • कोष्ठक के बाहर, |बहुत कसकर बांधता है, इसलिए

    command1 | command2 || command3

    के बराबर है

    ( command1 | command2 )  ||  command3

    और &&और ||अधिक कठोर बाँध ;, इसलिए

    command1 && command2 ; command3

    के बराबर है

    ( command1 && command2 ) ;  command3

    यानी, और / या command3के निकास स्थिति की परवाह किए बिना निष्पादित किया जाएगा ।command1command2


बिल्कुल सही, +1! मैंने कहा कि वे प्रासंगिक नहीं थे क्योंकि मैं उतना विस्तार नहीं करना चाहता था। मैं एक उत्तर चाहता था जो कि newbies के लिए एक त्वरित चीटशीट के रूप में काम कर सकता है जो सोच रहे हैं कि विभिन्न कमांडों के अंत में सभी अजीब स्क्विगल्स क्या हैं। मेरा मतलब यह नहीं था कि वे उपयोगी नहीं हैं। यह सब जोड़ने के लिए धन्यवाद।
terdon

1
मैं "गंभीर जन" समस्या के बारे में चिंतित हूं - अगर हम सब कुछ पोस्ट करते हैं जो हम संभवतः गोले के बारे में कह सकते हैं, तो हम अपने स्वयं के टीएल के साथ समाप्त करेंगे ; बैश संदर्भ मैनुअल के डॉ संस्करण।
जी-मैन

इसके अलावा उल्लेख के लायक: सी परिवार की भाषाओं के विपरीत, ;स्वयं द्वारा (या बिना किसी पूर्व आदेश के) एक वाक्यविन्यास त्रुटि है, न कि एक खाली बयान। इस प्रकार ; ;एक त्रुटि है। (नए उपयोगकर्ताओं के लिए एक आम ख़तरा, IMHO)। भी: बयानों के ;;लिए, एक विशेष परिसीमन है case
मूरू

1
@ ममरू: अच्छी बात है, लेकिन चलो इसे सामान्य करते हैं। किसी भी नियंत्रण ऑपरेटरों कि आदेशों के बीच दिखाए जा सकते हैं: ;, &&, ||, &, और |, त्रुटियों यदि वे उन्हें पूर्ववर्ती कुछ भी नहीं के साथ दिखाई देते हैं। इसके अलावा, टेरडन ने ;;अपने जवाब में (संक्षेप में) संबोधित किया ।
जी-मैन

1
@Wildcard: ठीक है, मैं देखता हूं कि आप कहां से आ रहे हैं। मुख्य शब्द "हो सकता है"; मैं यह कह रहा था कि मैं इस बात की गारंटी नहीं देता कि सभी गोले इस तरह के निर्माण (यानी, वाईएमएमवी) को स्वीकार करेंगे। जाहिर है मैंने लिखा है कि इससे पहले कि मैं linebreakपोसिक्स खोल व्याकरण में टोकन के उपयोग के बारे में जानता था । इसलिए शायद यह कहना सुरक्षित है कि सभी POSIX- आज्ञाकारी गोले उन्हें स्वीकार करेंगे। मैं एक सामान्य अस्वीकरण के रूप में अपने बयान के साथ खड़ा हूं; यदि आपको एक पुराना पर्याप्त पूर्व-पॉसिक्स शेल मिलता है, जैसे कि वास्तविक बॉर्न शेल या पुराने, सभी दांव बंद हैं।
जी-मैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.