आप यहां दस्तावेज़ों और बिल्ली के संयोजन में आउटपुट पुनर्निर्देशन का उपयोग कैसे करते हैं?


56

मान लीजिए कि मेरे पास एक स्क्रिप्ट है जिसे मैं किसी अन्य कमांड पर पाइप करना चाहता हूं या किसी फ़ाइल पर रीडायरेक्ट करना चाहता हूं ( shउदाहरणों के लिए पाइपिंग )। मान लें कि मैं बैश का उपयोग कर रहा हूं।

मैं इसका उपयोग कर सकता है echo:

echo "touch somefile
echo foo > somefile" | sh

मैं भी लगभग एक ही काम कर सकता है cat:

cat << EOF
touch somefile
echo foo > somefile
EOF

लेकिन अगर मैं "EOF" को "EOF | sh" से बदल दूं तो यह सिर्फ यह सोचता है कि यह हेरेडोक का एक हिस्सा है।

मैं इसे कैसे बना सकता हूं ताकि catस्टड से पाठ का आउटपुट हो, और फिर इसे एक अनियंत्रित स्थान पर पाइप कर सके?


touchजब तक वहाँ है, वास्तव में आप क्या चाहते हैं? क्या सिर्फ इनपुट फ़ाइल पढ़ी जाती है और स्टडआउट के साथ दूसरे पर रीडायरेक्ट की जाती है?
राहुल पाटिल

2
@RahulPatil बेशक यह बेकार है। मैं सिर्फ एक से अधिक लाइन के साथ एक उदाहरण चाहता था, बेहतर ढंग से चित्रण करने के लिए। और उदाहरण का उपयोग करके देखें echo- मैं सोच रहा था कि इसके बराबर का उपयोग क्या होगा cat
स्ट्रगलर

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

जवाबों:


91

ऐसा करने के कई तरीके हैं। सबसे सरल शायद यह है:

cat <<EOF | sh
touch somefile
echo foo > somefile
EOF

एक और, जो मेरी राय में अच्छा वाक्यविन्यास है:

(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh

यह भी काम करता है, लेकिन बिना सबस्क्रिप्शन के:

{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh

अधिक विविधताएं:

cat <<EOF |
touch somefile
echo foo > somefile
EOF
  sh

या:

{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF

वैसे, मुझे उम्मीद है कि catआपके प्रश्न का उपयोग किसी और चीज़ के लिए प्लेसहोल्डर है। यदि नहीं, तो इसे बाहर निकालें, जैसे:

sh <<EOF
touch somefile
echo foo > somefile
EOF

इसे सरल बनाया जा सकता है:

sh -c 'touch somefile; echo foo > somefile'

या:

sh -c 'touch somefile
echo foo > somefile'

पाइपिंग के बजाय आउटपुट को पुनर्निर्देशित करना

sh >out <<EOF
touch somefile
echo foo > somefile
EOF

catके बराबर पाने के लिए उपयोग करना echo test > out:

cat >out <<EOF
test
EOF

एकाधिक यहाँ दस्तावेज़

( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2

यह उत्पादन का उत्पादन करता है:

hi
---
there

यहाँ क्या हो रहा है:

  • खोल देखता है ( ... )और संलग्न कमांड को एक उपधारा में चलाता है।
  • बिल्ली और गूंज काफी सरल हैं। cat <&3फ़ाइल वर्णनकर्ता के साथ बिल्ली को चलाने के लिए कहते हैं (FD) 0 (stdin) fd 3 से निर्देशित कर दिये; दूसरे शब्दों में, fd 3 से इनपुट को बाहर निकालो।
  • (...)आरंभ करने से पहले , शेल यहां दो दस्तावेज़ों को रीडायरेक्ट करता है और fd 0 ( <<EOF) और fd 3 ( 3<<EOF2) पाइप के रीड-साइड के साथ प्रतिस्थापित करता है
  • एक बार प्रारंभिक कमांड शुरू होने के बाद, शेल अपने स्टड को तब तक पढ़ता है जब तक EOF नहीं पहुंच जाता है और उसे पहले पाइप के राइट-साइड भेज देता है
  • इसके बाद, यह EOF2 और दूसरे पाइप के राइट-साइड के साथ भी ऐसा ही करता है

दूसरा-से-अंतिम उदाहरण दिया गया है, क्या आप पाइपिंग के बजाय स्टडआउट पुनर्निर्देशन के साथ एक उदाहरण दे सकते हैं?
स्ट्रगलर

मैंने उत्तर को पुनर्निर्देशित उदाहरण के साथ संपादित किया; क्या यह वह रूप है जिसे आप संपादित करना चाहते थे? यदि नहीं, तो क्या आप स्पष्ट करने के लिए उस हिस्से की पहली पंक्ति दे सकते हैं?
राख

1
यह समझने में मदद मिल सकती है कि शेल कैसे प्रक्रिया करता है। जब यह कमांड-लाइन का मूल्यांकन कर रहा है और << EOF को ढूंढता है, तो यह तब तक मानक इनपुट से पढ़ता है जब तक कि केवल EOF के साथ एक लाइन नहीं मिलती है, या अंत-इनपुट। मूल कमांड-लाइन पर बाकी सब कुछ जो अभी तक अप्रमाणित है, फिर भी प्रक्रिया जारी है। इसलिए, उदाहरण के लिए, ऐसा कुछ करना संभव है: (cat; echo ---; exec <&3; cat) <<EOF 3<<EOF2 >outऔर फिर एक पंक्ति में दो यहाँ-ब्लॉक के साथ उस कमांड इनपुट को दें।
राख

शेल प्रसंस्करण की आपकी व्याख्या दिलचस्प थी, लेकिन मेरे सिर पर :) जो मैं जानना चाहता था कि एक हेरेडोक का उपयोग करने के catबराबर क्या होगा echo test > out। जबकि आपके दिए गए उदाहरण ने पाइप के अंत में एक पुनर्निर्देशन जोड़ा।
स्ट्रगलर

1
@OlivierDulac - मैंने उत्तर में कई heredoc उदाहरण जोड़े।
राख

1

मैं केवल यह बताना चाहता हूं कि उपयोग meowकरना वैसा ही है जैसा कि मान्य है EOF

यह स्क्रिप्ट Meow!नाम की एक फ़ाइल में संलग्न होगी cat:

#!/bin/sh
cat <<meow>> cat
Meow!
meow

के रूप में सहेजें catsऔर इसे निष्पादन योग्य बनाएं chmod +x cats, फिर इसे इसके साथ चलाएं ./cats:

$ ./cats
$ cat cat
Meow!
$ ./cats
$ cat cat
Meow!
Meow!

स्पष्टीकरण:

  • cat <<meowहै यहाँ दस्तावेज़ वाक्य रचना। यह स्क्रिप्ट को निर्देश देता है कि इस पंक्ति का अनुसरण करने वाले टेक्स्ट के ब्लॉक को तब तक उठाएं, जब तक कि यह स्ट्रिंग का सामना न कर दे meow। तब सामग्री को आउटपुट किया जाएगा (या साथ पाइप किया जाएगा)।
  • >> catनाम की फ़ाइल में पाइप cat
  • के >बजाय का उपयोग करने के >>बजाय यह करने के लिए फ़ाइल को अधिलेखित कर देगा।
  • Meow!यहाँ दस्तावेज़ की सामग्री है ।
  • meowयहाँ दस्तावेज़ के लिए अंतिम मार्कर है । सामग्री, के उपयोग के साथ >>, के लिए संलग्न हैं cat

दोनों stdout और एक फ़ाइल के लिए Piping:

आपके द्वारा अनुरोध किए जाने वाले पाइपिंग को करने के लिए, यहां कोई दस्तावेज़ की आवश्यकता नहीं है।

catटेक्स्ट को आउटपुट नहीं कर सकते हैं और टेक्स्ट को पास नहीं कर सकते हैं, लेकिन teeजो आप पूछ रहे हैं उसके लिए एक सही मेल है:

echo echo | tee tee

यह स्ट्रिंग को आउटपुट करेगा echoऔर echoनामित फ़ाइल में लिखेगा tee

आप आउटपुट को भी पास कर सकते हैं cat, यदि वह आवश्यकता का हिस्सा है, या तो साथ:

echo echo | tee tee | cat </dev/stdin

या केवल:

echo echo | tee tee | cat

फ़ाइल की सामग्री:

$ cat tee
echo

1
यह वास्तव में सवाल का जवाब नहीं देता है। इसके अलावा >पाइप नहीं बनाता है क्योंकि आपकी आखिरी गोली निकलती है।
शरणार्थी

2
@strugee, जब एक ही fd को कई बार पुनर्निर्देशित किया जाता है या , जहाँ दोनों को और फ़ाइल के आउटपुट को खिलाने के लिए आंतरिक लागू करता है , में >पाइप बना सकता है । zshecho foo >&1 > teeecho foo > tee | catzshteeechocattee
स्टीफन चेज़लस

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