मैं बैश स्क्रिप्ट में फ़ाइल के लिए एक हेरेडोक कैसे लिख सकता हूं?


जवाबों:


1070

एडवांस बैश-स्क्रिप्टिंग गाइड चैप्टर 19 को पढ़ें । यहां दस्तावेज

यहां एक उदाहरण दिया गया है जो सामग्री को फ़ाइल में लिख देगा /tmp/yourfilehere

cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
        This line is indented.
EOF

ध्यान दें कि अंतिम 'EOF' (The LimitString) शब्द के सामने कोई व्हाट्सएप नहीं होना चाहिए, क्योंकि इसका मतलब है कि LimitStringमान्यता प्राप्त नहीं होगी।

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

#!/usr/bin/env bash

if true ; then
    cat <<- EOF > /tmp/yourfilehere
    The leading tab is ignored.
    EOF
fi

यदि आप पाठ में चर की व्याख्या नहीं करना चाहते हैं, तो एकल उद्धरणों का उपयोग करें:

cat << 'EOF' > /tmp/yourfilehere
The variable $FOO will not be interpreted.
EOF

एक कमांड पाइपलाइन के माध्यम से हेरेडोक को पाइप करने के लिए:

cat <<'EOF' |  sed 's/a/b/'
foo
bar
baz
EOF

आउटपुट:

foo
bbr
bbz

... या फ़ाइल का उपयोग करने के लिए हेरेडोक लिखने के लिए sudo:

cat <<'EOF' |  sed 's/a/b/' | sudo tee /etc/config_file.conf
foo
bar
baz
EOF

11
आपको बैश की भी आवश्यकता नहीं है, यह सुविधा बॉर्न / कोर्न / पोसिक्स गोले में भी है।
Janus Troelsen

5
किस बारे में <<<, उन्हें क्या कहा जाता है?
जर्गेन पॉल

18
@PeaeappleUndertheSea <<<को 'यहां स्ट्रिंग्स' कहा जाता है। जैसे कोड tr a-z A-Z <<< 'one two three'स्ट्रिंग में परिणाम होगा ONE TWO THREEEn.wikipedia.org/wiki/Here_document#Here_strings
Stefan Lasiewski

8
अंतिम ईओएफ में इसके बाद कोई व्हाट्सएप नहीं होना चाहिए । कम से कम बैश पर, इस परिणाम के रूप में पहचाना नहीं जा रहा है सीमांकक के रूप में
कार्पी

10
चूँकि यह विशेष रूप से हेरेडोक का अर्थ शाब्दिक सामग्री है, जिसमें प्रतिस्थापन शामिल नहीं है, बल्कि इसके <<'EOF'बजाय होना चाहिए <<EOF
चार्ल्स डफी

152

उपयोग करने के बजाय catऔर I / O पुनर्निर्देशन के teeबजाय इसका उपयोग करना उपयोगी हो सकता है :

tee newfile <<EOF
line 1
line 2
line 3
EOF

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


18
मैं > /dev/nullपहली पंक्ति के अंत में जोड़ने की सलाह दूंगा कि जब यह बनाया जाता है तो फाइल को यहां प्रदर्शित होने से रोकने के लिए सामग्री को रोका जाए।
जो कैरोल

11
सच है, लेकिन अपने समाधान की वजह से अपनी अनुकूलता की वजह से मुझसे अपील की sudo, बल्कि अपनी संक्षिप्तता की वजह से :-)
जो कैरोल

2
मौजूदा फ़ाइल में संलग्न करने के लिए आप इस विधि का उपयोग कैसे करेंगे?
माउंटेनएक्स

5
@MountainX बाहर की जाँच करें man tee-aअधिलेखित करने के बजाय ध्वज का उपयोग करें ।
Livven

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

59

ध्यान दें:

प्रश्न (कैसे यहाँ दस्तावेज़ लिखने के लिए (उर्फ हेरेडोक ) को बैश स्क्रिप्ट में फाइल में?) कम से कम 3 मुख्य स्वतंत्र आयाम या उपश्रेणियाँ हैं:

  1. क्या आप किसी मौजूदा फ़ाइल को अधिलेखित करना चाहते हैं, एक मौजूदा फ़ाइल में संलग्न हैं, या एक नई फ़ाइल लिखना चाहते हैं?
  2. क्या आपका उपयोगकर्ता या कोई अन्य उपयोगकर्ता (जैसे root) फ़ाइल का मालिक है?
  3. क्या आप अपने हेरेडोक की सामग्री को शाब्दिक रूप से लिखना चाहते हैं या बैश की व्याख्या अपने हेरेडोक के अंदर चर संदर्भों के लिए करना चाहते हैं?

(अन्य आयाम / उपकथाएं हैं जिन्हें मैं महत्वपूर्ण नहीं मानता हूं। उन्हें जोड़ने के लिए इस उत्तर को संपादित करने पर विचार करें!) यहां ऊपर दिए गए प्रश्न के आयामों के कुछ और महत्वपूर्ण संयोजन हैं, विभिन्न विभिन्न परिसीमन पहचानकर्ताओं के साथ - कुछ भी नहीं है के बारे में पवित्र EOF, बस यह सुनिश्चित करें कि आपके द्वारा पहचाने जाने वाले स्ट्रिंग का उपयोग आपके वंशानुगत के अंदर नहीं होता है:

  1. मौजूदा फ़ाइल को अधिलेखित करने के लिए (या नई फ़ाइल पर लिखें) जो आपके पास है, जो हेरेडोक के अंदर चर संदर्भों को प्रतिस्थापित करती है:

    cat << EOF > /path/to/your/file
    This line will write to the file.
    ${THIS} will also write to the file, with the variable contents substituted.
    EOF
  2. मौजूदा फ़ाइल को जोड़ने के लिए (या नई फ़ाइल पर लिखें) जो आपके पास है, हेरेडोक के अंदर चर संदर्भों को प्रतिस्थापित करना:

    cat << FOE >> /path/to/your/file
    This line will write to the file.
    ${THIS} will also write to the file, with the variable contents substituted.
    FOE
  3. मौजूदा फ़ाइल को अधिलेखित करने के लिए (या नई फ़ाइल पर लिखें) जो आपके पास है, जो हेरेडॉक की शाब्दिक सामग्री के साथ है:

    cat << 'END_OF_FILE' > /path/to/your/file
    This line will write to the file.
    ${THIS} will also write to the file, without the variable contents substituted.
    END_OF_FILE
  4. मौजूदा फ़ाइल को संलग्न करने के लिए (या नई फ़ाइल पर लिखें) जो आपके पास है, जो हेरेडोक की शाब्दिक सामग्री के साथ है:

    cat << 'eof' >> /path/to/your/file
    This line will write to the file.
    ${THIS} will also write to the file, without the variable contents substituted.
    eof
  5. एक मौजूदा फ़ाइल को अधिलेखित करने के लिए (या एक नई फ़ाइल के लिए लिखें) जड़ के स्वामित्व में, हेरेडोक के अंदर चर संदर्भों को प्रतिस्थापित करना:

    cat << until_it_ends | sudo tee /path/to/your/file
    This line will write to the file.
    ${THIS} will also write to the file, with the variable contents substituted.
    until_it_ends
  6. मौजूदा फ़ाइल (या एक नई फ़ाइल लिखने के लिए) के लिए उपयोगकर्ता = foo के स्वामित्व वाली, हेरेड की शाब्दिक सामग्री के साथ:

    cat << 'Screw_you_Foo' | sudo -u foo tee -a /path/to/your/file
    This line will write to the file.
    ${THIS} will also write to the file, without the variable contents substituted.
    Screw_you_Foo

# 6 सबसे अच्छा है। लेकिन आप मौजूदा फ़ाइल की सामग्री को # 6 के साथ कैसे अधिलेखित कर सकते हैं?
अलेक्सांद्र माकोव

2
@ अलेक्जेंडर माकोव: आप मौजूदा फ़ाइल की सामग्री को # 6 के साथ कैसे अधिलेखित करते हैं? ओमित -a== --append; यानी, tee -a-> tee। देखें info tee(मैं इसे यहाँ उद्धृत करूँगा, लेकिन टिप्पणी मार्कअप बहुत सीमित है।
टॉमरोक

1
# 6 का उपयोग करने के बजाय बिल्ली और पाइपिंग का उपयोग करने का कोई लाभ है sudo tee /path/to/your/file << 'Screw_you_Foo'?
कोडोमेंकी

FOEइसके बजाय EOFपरिशिष्ट उदाहरण में क्यों ?
बेको

2
@becko: केवल यह बताने के लिए कि लेबल सिर्फ एक लेबल है। ध्यान दें कि मैंने प्रत्येक उदाहरण में एक अलग लेबल का उपयोग किया है।
TomRoche

41

@ Livven के उत्तर को बनाने के लिए , यहां कुछ उपयोगी संयोजन दिए गए हैं।

  1. चर प्रतिस्थापन, प्रमुख टैब बनाए रखा, फ़ाइल अधिलेखित, गूंज stdout करने के लिए

    tee /path/to/file <<EOF
    ${variable}
    EOF
  2. कोई चर प्रतिस्थापन , प्रमुख टैब बनाए रखा, फ़ाइल को अधिलेखित, गूंज stdout करने के लिए

    tee /path/to/file <<'EOF'
    ${variable}
    EOF
  3. चर प्रतिस्थापन, प्रमुख टैब हटा दिया गया है , फ़ाइल को अधिलेखित करें, प्रतिध्वनित प्रतिध्वनि

    tee /path/to/file <<-EOF
        ${variable}
    EOF
  4. चर प्रतिस्थापन, अग्रणी टैब बनाए रखा, फ़ाइल करने के लिए संलग्न , प्रतिध्वनि करने के लिए गूंज

    tee -a /path/to/file <<EOF
    ${variable}
    EOF
  5. चर प्रतिस्थापन, अग्रणी टैब बनाए रखा, फ़ाइल को अधिलेखित, stdout करने के लिए कोई गूंज

    tee /path/to/file <<EOF >/dev/null
    ${variable}
    EOF
  6. इसके बाद के संस्करण के साथ जोड़ा जा सकता है sudoऔर साथ ही

    sudo -u USER tee /path/to/file <<EOF
    ${variable}
    EOF

16

जब रूट अनुमतियों की आवश्यकता होती है

गंतव्य फ़ाइल के लिए रूट अनुमतियाँ आवश्यक हैं, |sudo teeइसके बजाय का उपयोग करें >:

cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF

क्या यहां दस्तावेज़ों के लिए चर पास करना संभव है? आप इसे कैसे प्राप्त कर सकते हैं इसलिए $ FOO की व्याख्या की गई थी?
user1527227

@ user1527227 यहाँ उदाहरण के रूप में फ़ाइल कहती है: चर $ FOO की व्याख्या नहीं की जाएगी।
सर्ज स्ट्रोबंड्ट

नीचे मैंने इसके साथ इस उत्तर को संयोजित करने और व्यवस्थित करने का प्रयास किया है स्टीफन लासिवस्की के
टॉमक्रॉ

3
@ user1527227 ईओएफ को सिंगल कोट्स में संलग्न न करें। तब $ FOO की व्याख्या की जाएगी।
imnd_neel

11

भविष्य के लोगों के लिए, जिनके पास यह समस्या हो सकती है, निम्न प्रारूप में काम किया है:

(cat <<- _EOF_
        LogFile /var/log/clamd.log
        LogTime yes
        DatabaseDirectory /var/lib/clamav
        LocalSocket /tmp/clamd.socket
        TCPAddr 127.0.0.1
        SelfCheck 1020
        ScanPDF yes
        _EOF_
) > /etc/clamd.conf

6
कोष्ठक की आवश्यकता नहीं है: cat << END > afileइसके बाद हेरेडोक पूरी तरह से अच्छी तरह से काम करता है।
ग्लेन जैकमैन

धन्यवाद, यह वास्तव में मैं भाग गया एक और मुद्दा हल। यहाँ कुछ डॉक्स के बाद कुछ मुद्दे थे। मुझे लगता है कि इसे पारेंस के साथ करना था, जैसा कि ऊपर की सलाह के साथ तय किया गया था।
जोशुआ एनफील्ड

2
यह काम नहीं करेगा। आउटपुट पुनर्निर्देशन को उस पंक्ति के अंत में होना चाहिए, जो catस्वीकृत उत्तर में दिखाए गए अनुसार शुरू होता है ।
अगली सूचना तक रोक दिया गया।

2
@ डेनिसविलियम्सन यह काम करता है, यही परन्स के लिए है। संपूर्ण catएक उप-प्रकार के अंदर चलता है, और
उप

2
@ इज़काटा: यदि आप इस उत्तर के संपादित इतिहास को देखते हैं, तो मुझे टिप्पणी करने से पहले कोष्ठक हटा दिए गए थे और बाद में वापस जोड़ दिया गया था। ग्लेन जैकमैन (और मेरी) टिप्पणी लागू होती है।
अगली सूचना तक रोक दिया गया।

3

उदाहरण के लिए आप इसका उपयोग कर सकते हैं:

पहला (ssh कनेक्शन बनाना):

while read pass port user ip files directs; do
    sshpass -p$pass scp -o 'StrictHostKeyChecking no' -P $port $files $user@$ip:$directs
done <<____HERE
    PASS    PORT    USER    IP    FILES    DIRECTS
      .      .       .       .      .         .
      .      .       .       .      .         .
      .      .       .       .      .         .
    PASS    PORT    USER    IP    FILES    DIRECTS
____HERE

दूसरा (कमांड निष्पादित करना):

while read pass port user ip; do
    sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1
    COMMAND 1
    .
    .
    .
    COMMAND n
ENDSSH1
done <<____HERE
    PASS    PORT    USER    IP
      .      .       .       .
      .      .       .       .
      .      .       .       .
    PASS    PORT    USER    IP    
____HERE

तीसरा (कमांड निष्पादित करना):

Script=$'
#Your commands
'

while read pass port user ip; do
    sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port $user@$ip "$Script"

done <<___HERE
PASS    PORT    USER    IP
  .      .       .       .
  .      .       .       .
  .      .       .       .
PASS    PORT    USER    IP  
___HERE

फोर्थ (चर का उपयोग करके):

while read pass port user ip fileoutput; do
    sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port $user@$ip fileinput=$fileinput 'bash -s'<<ENDSSH1
    #Your command > $fileinput
    #Your command > $fileinput
ENDSSH1
done <<____HERE
    PASS    PORT    USER    IP      FILE-OUTPUT
      .      .       .       .          .
      .      .       .       .          .
      .      .       .       .          .
    PASS    PORT    USER    IP      FILE-OUTPUT
____HERE

-1

मुझे इंडेंटेड स्क्रिप्ट में कॉन्सेप्ट, पठनीयता और प्रस्तुति के लिए यह तरीका पसंद है:

<<-End_of_file >file
       foo bar
End_of_file

→       एक tabपात्र कहां है ।

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