Bash
पुनर्निर्देशन
खोज…
वाक्य - विन्यास
- कमांड </ path / to / file # फ़ाइल पर पुनर्निर्देशित मानक इनपुट
- कमांड> / पथ / / / फ़ाइल # रीडायरेक्ट मानक आउटपुट को फ़्लिप करने के लिए
- कमांड file_descriptor> / path / to / file # फ़ाइल का रीडायरेक्ट आउटपुट फाइल करने के लिए
- कमांड> और file_descriptor # file_descriptor पर पुनर्निर्देशित आउटपुट
- कमांड file_descriptor> और other_file_descriptor # पुनर्निर्देशित file_descriptor दूसरे_file_descriptor को
- कमांड <और file_descriptor # पुनर्निर्देशित file_descriptor मानक इनपुट के लिए
- कमांड एंड> / पाथ / टू / फाइल # रीडायरेक्ट स्टैंडर्ड आउटपुट और फाइल करने के लिए स्टैंडर्ड एरर
पैरामीटर
पैरामीटर | विवरण |
---|---|
आंतरिक फ़ाइल विवरणक | पूर्णांक। |
दिशा | > , < या <> |
बाहरी फ़ाइल विवरणक या पथ | & फ़ाइल डिस्क्रिप्टर या पथ के लिए एक पूर्णांक द्वारा पीछा किया। |
टिप्पणियों
UNIX कंसोल प्रोग्राम में एक इनपुट फ़ाइल और दो आउटपुट फाइलें (इनपुट और आउटपुट स्ट्रीम, साथ ही डिवाइस, ओएस द्वारा व्यवहार किए जाते हैं।) ये आम तौर पर क्रमशः कीबोर्ड और स्क्रीन होते हैं, लेकिन उनमें से किसी या सभी को पुनर्निर्देशित किया जा सकता है। से आने के लिए - या एक फ़ाइल या अन्य कार्यक्रम के लिए जाना।
STDIN
मानक इनपुट है, और यह है कि प्रोग्राम कैसे इंटरएक्टिव इनपुट प्राप्त करता है। STDIN
को आमतौर पर फाइल डिस्क्रिप्टर 0 दिया जाता है।
STDOUT
मानक आउटपुट है। STDOUT
पर जो भी उत्सर्जित होता है, उसे कार्यक्रम का "परिणाम" माना जाता है। STDOUT
को आमतौर पर फाइल डिस्क्रिप्टर 1 दिया जाता है।
STDERR
वह जगह है जहाँ त्रुटि संदेश प्रदर्शित होते हैं। आमतौर पर, कंसोल से प्रोग्राम चलाते समय, STDERR
स्क्रीन पर आउटपुट होता है और STDOUT
से अप्रभेद्य होता है। STDERR
को आमतौर पर फाइल डिस्क्रिप्टर 2 दिया जाता है।
पुनर्निर्देशन का क्रम महत्वपूर्ण है
command > file 2>&1
फ़ाइल में ( STDOUT
और STDERR
) दोनों को रीडायरेक्ट करता है।
command 2>&1 > file
केवल STDOUT
पुनर्निर्देशित करता है, क्योंकि फ़ाइल डिस्क्रिप्टर 2 फ़ाइल डिस्क्रिप्टर 1 (जो स्टेटमेंट का मूल्यांकन होने पर अभी तक फ़ाइल file
नहीं है) द्वारा इंगित फ़ाइल पर रीडायरेक्ट होता है।
एक पाइपलाइन में प्रत्येक कमांड का अपना STDERR
(और STDOUT
) है क्योंकि प्रत्येक एक नई प्रक्रिया है। यदि आप पूरे पाइपलाइन को प्रभावित करने के लिए पुनर्निर्देशित की अपेक्षा करते हैं तो यह आश्चर्यजनक परिणाम पैदा कर सकता है। उदाहरण के लिए इस कमांड (लेगबिलिटी के लिए लिपटे हुए):
$ python -c 'import sys;print >> sys.stderr, "Python error!"' \
| cut -f1 2>> error.log
"पायथन त्रुटि" प्रिंट करेगा! लॉग फ़ाइल के बजाय कंसोल के लिए। इसके बजाय, उस त्रुटि को संलग्न करें जिसे आप कैप्चर करना चाहते हैं:
$ python -c 'import sys;print >> sys.stderr, "Python error!"' 2>> error.log \
| cut -f1
मानक आउटपुट पुनर्निर्देशित करना
>
वर्तमान कमांड (उर्फ STDOUT
) को वर्तमान कमांड के फ़ाइल या किसी अन्य डिस्क्रिप्टर में रीडायरेक्ट करता है।
ये उदाहरण ls
कमांड के आउटपुट को फाइल file.txt
में लिखते हैं
ls >file.txt
> file.txt ls
यदि यह मौजूद नहीं है तो लक्ष्य फ़ाइल बनाई जाती है, अन्यथा यह फ़ाइल काट दी जाती है।
डिफ़ॉल्ट पुनर्निर्देशन डिस्क्रिप्टर मानक आउटपुट या 1
जब कोई भी निर्दिष्ट नहीं किया जाता है। यह कमांड पिछले उदाहरणों के बराबर है जिसमें मानक आउटपुट स्पष्ट रूप से दर्शाया गया है:
ls 1>file.txt
नोट: पुनर्निर्देशन निष्पादित शेल द्वारा आरंभ किया गया है और निष्पादित कमांड द्वारा नहीं किया गया है, इसलिए यह कमांड निष्पादन से पहले किया जाता है।
एसटीडीआई पुनर्निर्देशित करना
<
अपने दाहिने तर्क से पढ़ता है और अपने बाएं तर्क को लिखता है।
STDIN
में एक फ़ाइल लिखने के लिए हमें /tmp/a_file
को पढ़ना चाहिए और STDIN
में लिखना चाहिए अर्थात 0</tmp/a_file
नोट: आंतरिक फ़ाइल विवरणक <
लिए 0
( STDIN
) के लिए डिफॉल्ट करता है
$ echo "b" > /tmp/list.txt
$ echo "a" >> /tmp/list.txt
$ echo "c" >> /tmp/list.txt
$ sort < /tmp/list.txt
a
b
c
STDOUT और STDERR दोनों को पुनर्निर्देशित करना
फ़ाइल डिस्क्रिप्टर 0
और 1
जैसे बिंदु हैं। हम बदलते हैं कि फ़ाइल विवरणकर्ता पुनर्निर्देशन के साथ क्या इंगित करता है। >/dev/null
अर्थ है 1
अंक /dev/null
।
पहले हम 1
( STDOUT
) को /dev/null
को इंगित करते हैं, फिर 2
( STDERR
) को जो भी 1
अंक बताते हैं।
# STDERR is redirect to STDOUT: redirected to /dev/null,
# effectually redirecting both STDERR and STDOUT to /dev/null
echo 'hello' > /dev/null 2>&1
इसे निम्नलिखित में छोटा किया जा सकता है:
echo 'hello' &> /dev/null
हालांकि, यह प्रपत्र उत्पादन में अवांछनीय हो सकता है यदि शेल संगतता एक चिंता है क्योंकि यह पोसिक्स के साथ टकराव करता है, पार्सिंग अस्पष्टता का परिचय देता है, और इस सुविधा के बिना गोले इसे गलत व्याख्या करेंगे:
# Actual code
echo 'hello' &> /dev/null
echo 'hello' &> /dev/null 'goodbye'
# Desired behavior
echo 'hello' > /dev/null 2>&1
echo 'hello' 'goodbye' > /dev/null 2>&1
# Actual behavior
echo 'hello' &
echo 'hello' & goodbye > /dev/null
नोट: &>
को बाश और ज़श दोनों में वांछित काम करने के लिए जाना जाता है।
पुनर्निर्देशन STDERR
2
STDERR
।
$ echo_to_stderr 2>/dev/null # echos nothing
परिभाषाएं:
echo_to_stderr
एक कमांड है जो STDERR
को "stderr"
लिखता है
echo_to_stderr () {
echo stderr >&2
}
$ echo_to_stderr
stderr
ट्रेंडकेट बनाम एपेंड करें
ट्रंकट >
- यदि यह मौजूद नहीं है, तो निर्दिष्ट फ़ाइल बनाएँ।
- काटें (फ़ाइल की सामग्री निकालें)
- दर्ज करने के लिए लिखें
$ echo "first line" > /tmp/lines
$ echo "second line" > /tmp/lines
$ cat /tmp/lines
second line
परिशिष्ट >>
- यदि यह मौजूद नहीं है, तो निर्दिष्ट फ़ाइल बनाएँ।
- फ़ाइल संलग्न करें (फ़ाइल के अंत में लेखन)।
# Overwrite existing file
$ echo "first line" > /tmp/lines
# Append a second line
$ echo "second line" >> /tmp/lines
$ cat /tmp/lines
first line
second line
STDIN, STDOUT और STDERR ने समझाया
कमांड में एक इनपुट (STDIN) और दो प्रकार के आउटपुट, मानक आउटपुट (STDOUT) और मानक त्रुटि (STDERR) होती है।
उदाहरण के लिए:
STDIN
root@server~# read
Type some text here
किसी प्रोग्राम को इनपुट प्रदान करने के लिए स्टैंडर्ड इनपुट का उपयोग किया जाता है। (यहां हम STDIN की एक पंक्ति पढ़ने के लिए read
बिल्ड का उपयोग कर रहे हैं।)
STDOUT
root@server~# ls file
file
मानक आउटपुट का उपयोग आम तौर पर कमांड से "सामान्य" आउटपुट के लिए किया जाता है। उदाहरण के लिए, ls
फाइलों को सूचीबद्ध करता है, इसलिए फाइलें STDOUT को भेजी जाती हैं।
STDERR
root@server~# ls anotherfile
ls: cannot access 'anotherfile': No such file or directory
मानक त्रुटि (जैसा कि नाम का अर्थ है) त्रुटि संदेशों के लिए उपयोग की जाती है। क्योंकि यह संदेश फ़ाइलों की सूची नहीं है, इसे STDERR को भेजा जाता है।
STDIN, STDOUT और STDERR तीन मानक धाराएँ हैं। उन्हें एक नाम के बजाय एक संख्या द्वारा शेल में पहचाना जाता है:
0 = मानक में
1 = मानक बाहर
2 = मानक त्रुटि
डिफ़ॉल्ट रूप से, STDIN कीबोर्ड से जुड़ा होता है, और STDOUT और STDERR दोनों टर्मिनल में दिखाई देते हैं। हालाँकि, हम अपनी ज़रूरत के हिसाब से या तो STDOUT या STDERR को रीडायरेक्ट कर सकते हैं। उदाहरण के लिए, मान लें कि आपको केवल मानक आउट की आवश्यकता है और मानक त्रुटि पर मुद्रित सभी त्रुटि संदेशों को दबा दिया जाना चाहिए। जब हम विवरण 1
और 2
उपयोग करते हैं।
STDERR को / dev / null पर पुनर्निर्देशित करना
पिछला उदाहरण लेते हुए,
root@server~# ls anotherfile 2>/dev/null
root@server~#
इस स्थिति में, यदि कोई STDERR है, तो इसे / dev / null (एक विशेष फ़ाइल जो इसमें डाली गई किसी भी चीज़ को अनदेखा करती है) पर पुनर्निर्देशित किया जाएगा, इसलिए आपको शेल पर कोई त्रुटि आउटपुट नहीं मिलेगा।
एक ही फाइल में कई कमांड को रीडायरेक्ट करना
{
echo "contents of home directory"
ls ~
} > output.txt
नामित पाइप का उपयोग करना
कभी-कभी आप किसी प्रोग्राम के द्वारा कुछ आउटपुट करना चाहते हैं और उसे दूसरे प्रोग्राम में इनपुट कर सकते हैं, लेकिन एक मानक पाइप का उपयोग नहीं कर सकते।
ls -l | grep ".log"
आप बस एक अस्थायी फ़ाइल में लिख सकते हैं:
touch tempFile.txt
ls -l > tempFile.txt
grep ".log" < tempFile.txt
यह अधिकांश अनुप्रयोगों के लिए ठीक काम करता है, हालांकि, किसी को भी पता नहीं चलेगा कि tempFile
क्या करता है और कोई इसे हटा सकता है यदि इसमें उस निर्देशिका में ls -l
का आउटपुट शामिल है। यह वह जगह है जहाँ एक नामित पाइप खेल में आता है:
mkfifo myPipe
ls -l > myPipe
grep ".log" < myPipe
myPipe
तकनीकी रूप से एक फ़ाइल है (सब कुछ लिनक्स में है), तो चलिए ls -l
को एक खाली डायरेक्टरी में करते हैं जिसे हमने अभी एक पाइप बनाया है:
mkdir pipeFolder
cd pipeFolder
mkfifo myPipe
ls -l
आउटपुट है:
prw-r--r-- 1 root root 0 Jul 25 11:20 myPipe
अनुमतियों में पहले वर्ण को नोटिस करें, यह एक फ़ाइल के रूप में पाइप के रूप में सूचीबद्ध है।
अब कुछ ठंडा होने दो।
एक टर्मिनल खोलें, और निर्देशिका को नोट करें (या एक बनाएं ताकि सफाई आसान हो), और एक पाइप बनाएं।
mkfifo myPipe
अब पाइप में कुछ डालते हैं।
echo "Hello from the other side" > myPipe
आप इस हैंग को नोटिस करेंगे, पाइप का दूसरा किनारा अभी भी बंद है। चलो पाइप के दूसरी तरफ खुलते हैं और उस सामान को अंदर आने देते हैं।
एक और टर्मिनल खोलें और उस निर्देशिका में जाएं जहां पाइप अंदर है (या यदि आप इसे जानते हैं, तो इसे पाइप पर भेज दें):
cat < myPipe
आप देखेंगे कि hello from the other side
आउटपुट के बाद, पहले टर्मिनल में प्रोग्राम खत्म होता है, जैसा कि दूसरे टर्मिनल में होता है।
अब कमांड्स को रिवर्स में चलाएं। cat < myPipe
साथ शुरू करें cat < myPipe
और फिर cat < myPipe
कुछ cat < myPipe
। यह अभी भी काम करता है, क्योंकि एक कार्यक्रम तब तक इंतजार करेगा जब तक कि कुछ समाप्त होने से पहले पाइप में डाल दिया जाता है, क्योंकि यह जानता है कि इसे कुछ प्राप्त करना है।
टर्मिनलों के बीच या कार्यक्रमों के बीच चलती जानकारी के लिए नामांकित पाइप उपयोगी हो सकते हैं।
पाइप छोटे होते हैं। एक बार पूर्ण होने पर, लेखक तब तक ब्लॉक करता है जब तक कि कुछ पाठक सामग्री को नहीं पढ़ लेते हैं, इसलिए आपको पाठक और लेखक को अलग-अलग टर्मिनलों में चलाने या पृष्ठभूमि में एक या दूसरे को चलाने की आवश्यकता है:
ls -l /tmp > myPipe &
cat < myPipe
नामित पाइपों का उपयोग करने वाले अधिक उदाहरण:
उदाहरण 1 - एक ही टर्मिनल / एक ही शेल पर सभी कमांड
$ { ls -l && cat file3; } >mypipe & $ cat <mypipe # Output: Prints ls -l data and then prints file3 contents on screen
उदाहरण 2 - एक ही टर्मिनल / एक ही शेल पर सभी कमांड
$ ls -l >mypipe & $ cat file3 >mypipe & $ cat <mypipe #Output: This prints on screen the contents of mypipe.
ध्यान रखें कि पहले
file3
सामग्री प्रदर्शित होती है और फिरls -l
डेटा प्रदर्शित होता है (LIFO कॉन्फ़िगरेशन)।उदाहरण 3 - एक ही टर्मिनल / एक ही शेल पर सभी कमांड
$ { pipedata=$(<mypipe) && echo "$pipedata"; } & $ ls >mypipe # Output: Prints the output of ls directly on screen
ध्यान रखें कि चर
$pipedata
के उपयोग के बाद से मुख्य टर्मिनल / मुख्य खोल में उपयोग के लिए उपलब्ध नहीं है&
आह्वान एक subshell और$pipedata
इस subshell में ही उपलब्ध था।उदाहरण 4 - एक ही टर्मिनल / एक ही शेल पर सभी कमांड
$ export pipedata $ pipedata=$(<mypipe) & $ ls -l *.sh >mypipe $ echo "$pipedata" #Output : Prints correctly the contents of mypipe
यह चर के निर्यात घोषणा के कारण मुख्य शेल में
$pipedata
चर के मूल्य को सही ढंग से प्रिंट करता है। मुख्य टर्मिनल / मुख्य शेल एक पृष्ठभूमि शेल (&
) के आह्वान के कारण लटका नहीं है।
Stderr पर त्रुटि संदेश प्रिंट करें
त्रुटि संदेश आम तौर पर डीबगिंग उद्देश्यों के लिए या समृद्ध उपयोगकर्ता अनुभव प्रदान करने के लिए एक स्क्रिप्ट में शामिल होते हैं। बस इस तरह त्रुटि संदेश लिखने:
cmd || echo 'cmd failed'
साधारण मामलों के लिए काम कर सकते हैं लेकिन यह सामान्य तरीका नहीं है। इस उदाहरण में, त्रुटि संदेश स्क्रिप्ट की वास्तविक आउटपुट और stdout
में सफल आउटपुट दोनों को मिश्रित करके वास्तविक आउटपुट को प्रदूषित करेगा।
संक्षेप में, त्रुटि संदेश को stderr
को जाना चाहिए stdout
नहीं। यह बहुत आसान है:
cmd || echo 'cmd failed' >/dev/stderr
एक और उदाहरण:
if cmd; then
echo 'success'
else
echo 'cmd failed' >/dev/stderr
fi
उपरोक्त उदाहरण में, सफलता संदेश stdout
पर मुद्रित किया जाएगा, जबकि त्रुटि संदेश stderr
पर मुद्रित किया जाएगा।
फ़ंक्शन को परिभाषित करने के लिए त्रुटि संदेश प्रिंट करने का एक बेहतर तरीका है:
err(){
echo "E: $*" >>/dev/stderr
}
अब, जब आपको कोई त्रुटि प्रिंट करनी हो:
err "My error message"
नेटवर्क पते पर पुनर्निर्देशन
बैश कुछ पथों को विशेष मानता है और कुछ नेटवर्क संचार को /dev/{udp|tcp}/host/port
लिखकर कर सकता है। बैश एक सुनने वाले सर्वर को सेट नहीं कर सकता है, लेकिन एक कनेक्शन शुरू कर सकता है, और टीसीपी के लिए कम से कम परिणाम पढ़ सकते हैं।
उदाहरण के लिए, एक साधारण वेब अनुरोध भेजने के लिए कोई भी ऐसा कर सकता है:
exec 3</dev/tcp/www.google.com/80
printf 'GET / HTTP/1.0\r\n\r\n' >&3
cat <&3
और www.google.com
के डिफ़ॉल्ट वेब पेज के परिणाम को stdout
प्रिंट किया जाएगा।
उसी प्रकार
printf 'HI\n' >/dev/udp/192.168.1.1/6666
192.168.1.1:6666
पर एक श्रोता को HI\n
युक्त एक UDP संदेश भेजेगा