एक heredoc पाइपिंग के लिए बहुपरत सिंटैक्स; क्या यह पोर्टेबल है?


132

मैं इस वाक्य रचना से परिचित हूँ:

cmd1 << EOF | cmd2
text
EOF

लेकिन अभी पता चला है कि मार मुझे लिखने की अनुमति देता है:

cmd1 << EOF |
text
EOF
cmd2

(heredoc का उपयोग cmd1 के इनपुट के रूप में किया जाता है, और cmd1 के आउटपुट को cmd2 में पाइप किया जाता है)। यह एक बहुत ही अजीब वाक्य रचना की तरह लगता है। क्या यह पोर्टेबल है?


मैं इसे कई लाइनों में विभाजित करने का एक अच्छा तरीका खोजने के लिए यहाँ आया था big-long-command1 with lots of args << EOF | big-long-command2 with lots of args:। "विषम सिंटैक्स" सबसे अच्छा तरीका लगता है।
21

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

1-मेरे लिए z- शेल में काम नहीं किया। मुझे दूसरा पसंद नहीं है क्योंकि यह अलग है कमांड से, शेल पाइपलाइनों के मुहावरे (?) को खोना।
श्रीधर सरनोबत

जवाबों:


104

हां, POSIX मानक इसकी अनुमति देता है। 2008 के संस्करण के अनुसार:

यहां दस्तावेज़ को एक एकल शब्द के रूप में माना जाएगा जो अगले के बाद शुरू होता है <newline>और तब तक जारी रहता है जब तक कि कोई रेखा नहीं होती है जिसमें केवल सीमांकक और ए होता है <newline>, जिसके <blank>बीच कोई वर्ण नहीं होता है। फिर अगला यहाँ-दस्तावेज़ शुरू होता है, अगर वहाँ एक है।

और एक ही पंक्ति में कई "यहाँ-दस्तावेज़" का यह उदाहरण शामिल है:

cat <<eof1; cat <<eof2
Hi,
eof1
Helene.
eof2

इसलिए पुनर्निर्देश या पाइप करने में कोई समस्या नहीं है। आपका उदाहरण कुछ इस तरह है:

cat file |
cmd

और शेल व्याकरण (लिंक पेज पर और नीचे) में ये परिभाषाएँ शामिल हैं:

pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command

newline_list     :              NEWLINE
                 | newline_list NEWLINE
                 ;
linebreak        : newline_list
                 | /* empty */

तो एक पाइप प्रतीक का अंत-लाइन द्वारा पीछा किया जा सकता है और अभी भी एक पाइपलाइन का हिस्सा माना जा सकता है।


26

हाँ, यह POSIX शेल व्याकरण में है। आप एक ही कमांड के लिए एक से अधिक डॉक कर सकते हैं (कुछ अन्य उदाहरण दो catइनवोकेशन का उपयोग करते हैं , लेकिन यह भी काम करता है):

cat <<EOF1 <<EOF2
first here-doc
EOF1
second here-doc
EOF2

यह वंचित है (स्टडिन के लिए 2 यहां-डॉक्स का उपयोग करके), लेकिन अगर आप अलग-अलग फ़ाइल डिस्क्रिप्टर के लिए इनपुट प्रदान करने के बारे में सोचते हैं तो यह तुरंत समझ में आता है।

पूरी तरह से छोड़ने कीcat संभावना भी है । यहाँ दस्तावेज़ को सीधे उपलब्ध क्यों नहीं किया गया cmd:

cmd << EOF
input
here
EOF

`` `बिल्ली << EOF1 << EOF2 यहाँ पहले-डॉक्टर EOF1 यहाँ दूसरा-डॉक्टर EOF2` `` ऊपर काम नहीं करता है।
user1424739

@ user1424739 यह वर्तमान zsh और bash में काम करता है। राख और ksh93 केवल दूसरे के उत्पादन के लिए प्रतीत होते हैं।
जेन्स

क्यों होता है पतन? अगर कुछ गलत है, तो कृपया मुझे उपाय करने का अवसर दें।
जेन्स

उपयोग करते समय यह बहुत प्यारा है sudo tee /etc/securefile.conf <<EOF
ड्रैगन

किस बैश संस्करण पर यह काम करता है? बश 4.4.19 (उबंटू 18.04.02 पर) और बश 5.0 (डॉक इमेज) का उपयोग करते हुए, मुझे केवल यहां दूसरा-डॉक मिला। या शायद कोई विशिष्ट विकल्प है?
ह्युएलोबिस

17

हम्म, मुझे लगता है हां, पॉसिक्स मोड में बैश के अनुसार:

$ bash --posix
$ cat <<EOF |
> ahoj
> nazdar
> EOF
> sed 's/a/b/'
bhoj
nbzdar

सिर्फ एक अन्य छोटे नोट: समापन के बाद कोई स्थान न रखें EOF। संकेत अजीब व्यवहार करेगा और आपको आश्चर्य होगा कि नरक क्या गलत है
श्रीधर सरनोबत

2
POSIX- मोड में बैश चलाने से कुछ एक्सटेंशन बंद हो जाते हैं , लेकिन किसी भी तरह से उन सभी के बारे में भी नहीं। इस तरह, जबकि यह जवाब पॉसिक्स की अनुमति के संदर्भ में सही है, इसका तर्क बहुत प्रभावी ढंग से समर्थन नहीं करता है।
चार्ल्स डफी

3

हाय, यह जाँच करें, उदाहरण के लिए

#!/bin/sh
( base32 -d | base64 -d )<<ENDOFTEXT
KNDWW42DNNSHS5ZXPJCG4MSVM5MVQVT2JFCTK3DELBFDCY2IIJYGE2JUJNHWS22LINVHQMCMNVFD
CWJQIIZVUV2JOVNEOVJLINTW6PIK
ENDOFTEXT

सादर

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