यह एक पुराना सवाल है लेकिन एक चीज़ को स्पष्टीकरण की आवश्यकता है।
जबकि कार्ल नोरम और कुत्ते के जवाब सही हैं, धारणा काम करने के लिए अपनी स्क्रिप्ट को बदलती है।
#!/bin/bash
echo "This"
echo "is" >&2
echo "a" >&3
echo "test." >&4
यह काम करता है अगर आप इसे दूसरे तरीके से आह्वान:
./fdtest 3>&1 4>&1
जिसका अर्थ है
मैं बाहर बिंदु करना चाहते हैं क्या है कि आप स्क्रिप्ट को बदलने की जरूरत नहीं है फाइल डिस्क्रिप्टर 3 और 4 से 1 को रीडायरेक्ट करने के लिए (जो मानक आउटपुट है)।
मुद्दा यह है कि स्क्रिप्ट पूरी तरह से सिर्फ 1 और 2 (stdout और stderr) के अलावा अन्य वर्णनकर्ता में लिखने के लिए उन वर्णनकर्ता माता पिता प्रक्रिया द्वारा प्रदान की जाती है, तो चाहने में ठीक है।
आपका उदाहरण क्योंकि इस स्क्रिप्ट 4 अलग फ़ाइलों को लिख सकते हैं वास्तव में काफी दिलचस्प है:
./fdtest >file1.txt 2>file2.txt 3>file3.txt 4>file4.txt
अब आप 4 अलग फ़ाइलों में उत्पादन:
$ for f in file*; do echo $f:; cat $f; done
file1.txt:
This
file2.txt:
is
file3.txt:
a
file4.txt:
test.
अधिक दिलचस्प क्या है इसके बारे में यह है कि आपके प्रोग्राम में उन फ़ाइलों के लिए लिखने की अनुमति नहीं है, क्योंकि यह वास्तव में उन्हें नहीं खोलता है।
उदाहरण के लिए
, जब मैं sudo -s
चलाने के लिए, रूट करने के लिए उपयोगकर्ता को बदलने रूट के रूप में एक निर्देशिका बनाने, और मेरे नियमित उपयोगकर्ता इस तरह (मेरे मामले में आरएसपी) के रूप में निम्न आदेश को चलाने के लिए प्रयास करने के लिए:
# su rsp -c '../fdtest >file1.txt 2>file2.txt 3>file3.txt 4>file4.txt'
मैं एक त्रुटि मिलती है:
bash: file1.txt: Permission denied
लेकिन अगर मैं su
के बाहर पुनर्निर्देशन कार्य करें:
# su rsp -c '../fdtest' >file1.txt 2>file2.txt 3>file3.txt 4>file4.txt
(एकल उद्धरण में अंतर पर ध्यान दें) यह काम करता है और मैं:
# ls -alp
total 56
drwxr-xr-x 2 root root 4096 Jun 23 15:05 ./
drwxrwxr-x 3 rsp rsp 4096 Jun 23 15:01 ../
-rw-r--r-- 1 root root 5 Jun 23 15:05 file1.txt
-rw-r--r-- 1 root root 39 Jun 23 15:05 file2.txt
-rw-r--r-- 1 root root 2 Jun 23 15:05 file3.txt
-rw-r--r-- 1 root root 6 Jun 23 15:05 file4.txt
जो 4 जड़ के स्वामित्व वाले एक निर्देशिका में जड़ के स्वामित्व वाली फ़ाइलों कर रहे हैं - भले ही स्क्रिप्ट नहीं था उन फ़ाइलों को बनाने के लिए अनुमति।
एक और उदाहरण क्रोट जेल या कंटेनर का उपयोग करेगा और एक प्रोग्राम चलाएगा जहां उसे रूट के रूप में चलाने के बावजूद उन फ़ाइलों तक पहुंच नहीं होगी और फिर भी उन डिस्क्रिप्टर को बाहरी रूप से रीडायरेक्ट करें जहां आपको आवश्यकता है पूरी फाइल सिस्टम या इस स्क्रिप्ट के लिए और कुछ भी।
बिंदु यह है कि आपने एक बहुत ही रोचक और उपयोगी तंत्र खोजा है। आपको अन्य उत्तरों में सुझाए गए अनुसार आपकी स्क्रिप्ट के अंदर सभी फाइलें खोलने की ज़रूरत नहीं है। कभी-कभी स्क्रिप्ट आमंत्रण के दौरान उन्हें पुनर्निर्देशित करना उपयोगी होता है।
यह कुल मिलाकर के लिए, इस:
echo "This" >&1
और कार्यक्रम चलाने के रूप में:
./program >file.txt
रूप में ही है
echo "This"
वास्तव में के बराबर है:
./program 1>file.txt
नंबर 1 केवल एक डिफ़ॉल्ट संख्या है और यह stdout है।
लेकिन फिर भी इस कार्यक्रम:
#!/bin/bash
echo "This"
एक "बुरा वर्णनकर्ता" त्रुटि उत्पादन कर सकते हैं। कैसे? जब के रूप में चलाने:
./fdtest2 >&-
उत्पादन होगा:
./fdtest2: line 2: echo: write error: Bad file descriptor
>&-
जोड़ा जा रहा है (जो 1>&-
के समान है) मानक आउटपुट को बंद करने का मतलब है। 2>&-
जोड़ना मतलब है stderr बंद करना।
आप भी एक और जटिल चीज कर सकते हैं।आपका मूल स्क्रिप्ट:
#!/bin/bash
echo "This"
echo "is" >&2
echo "a" >&3
echo "test." >&4
बस के साथ चलते हैं तो:
./fdtest
प्रिंट:
This
is
./fdtest: line 4: 3: Bad file descriptor
./fdtest: line 5: 4: Bad file descriptor
लेकिन आप वर्णनकर्ता 3 और 4 काम कर सकते हैं, लेकिन नंबर 1 चलाकर असफल:
./fdtest 3>&1 4>&1 1>&-
यह आउटपुट:
./fdtest: line 2: echo: write error: Bad file descriptor
is
a
test.
आप वर्णनकर्ता दोनों 1 और 2 असफल हो, यह इस तरह से चलाने चाहते हैं:
./fdtest 3>&1 4>&1 1>&- 2>&-
आप मिल:
a
test.
क्यों? कुछ भी असफल नहीं हुआ? यह था लेकिन बिना stderr (फ़ाइल वर्णनकर्ता संख्या 2) आपको त्रुटि संदेश नहीं दिखाई दिए!
मुझे लगता है कि वर्णनकर्ताओं और उनके पुनर्निर्देशन के काम को महसूस करने के लिए इस तरह प्रयोग करना बहुत उपयोगी है।
आपकी स्क्रिप्ट वास्तव में एक बहुत ही रोचक उदाहरण है - और मैं तर्क देता हूं कि यह बिल्कुल टूटा नहीं है, आप बस इसे गलत इस्तेमाल कर रहे थे! :)
यही वह है जिसे मैं ढूंढ रहा हूं! तो मुझे exec कमांड के साथ अस्थायी स्टोरेज स्थान के रूप में उपयोग करने के लिए एक फ़ाइल निर्दिष्ट करने की आवश्यकता है, और फिर जब मैं कर रहा हूं तो उन्हें बंद कर दें? क्षमा करें, मैं exec कमांड के साथ थोड़ा अस्पष्ट हूं, मैं इसका अधिक उपयोग नहीं करता हूं। – Trcx
हाँ, लेकिन यह अस्थायी नहीं है। आपके प्रोग्राम को पूरा होने के बाद भी फ़ाइल मौजूद होगी। – dogbane
यह अच्छी तरह से काम कर सकता है, तो मैं क्रॉन्टाब कार्य शेड्यूलर के साथ संगत होने के लिए कुछ स्क्रिप्ट को पोर्ट करने की कोशिश कर रहा हूं, लेकिन मुझे परेशानी हो रही है क्योंकि क्रॉन स्क्रिप्ट में stdout की पाइपिंग की अनुमति नहीं देता है। – Trcx