विस्तार करने से आप पुनर्निर्देशन का कारण नहीं बन सकते हैं, यह "$HideErrors"
है कि जैसे प्रतीकों को >
विशेष रूप से पैरामीटर विस्तार द्वारा उत्पादित किए जाने के बाद इलाज नहीं किया जाता है । यह वास्तव में बहुत अच्छा है, क्योंकि इस तरह के प्रतीक पाठ में दिखाई देते हैं जिन्हें आप शाब्दिक रूप से विस्तारित और उपयोग करना चाहते हैं।
यह आप धारण करते हैं या नहीं $HideErrors
। पैरामीटर विस्तार का परिणाम शब्द के विभाजन और ग्लोबिंग के अधीन होता है जब विस्तार निर्विवाद होता है, लेकिन यह है।
इसके बारे में क्या करना है, सशर्त पुनर्निर्देशन प्राप्त करने के कई तरीके हैं। एक बहुत ही सरल आदेश के लिए, यह उचित हो सकता है कि संपूर्ण कमांड को दो बार लिखें, एक बार - case
या if
- else
कंस्ट्रक्शन की प्रत्येक शाखा में । हालांकि, यह जल्द ही बोझ बन जाता है, और आपके द्वारा दिखाई गई कमांड निश्चित रूप से एक ऐसा मामला है जहां यह आदर्श नहीं होगा।
उन दृष्टिकोणों में से जो आपको खुद को दोहराने से बचते हैं, दो मैं विशेष रूप से सलाह देते हैं, क्योंकि वे सही होने के लिए काफी साफ और आसान हैं। आप इनमें से सिर्फ एक का उपयोग करना चाहते हैं, एक ही आदेश और पुनर्निर्देशन दोनों के लिए नहीं।
पुनर्निर्देशन के बजाय कमांड स्टोर करें। एक चर में पुनर्निर्देशन को स्टोर करने और पैरामीटर विस्तार को लागू करने के बजाय, शेल फ़ंक्शन में कमांड स्टोर करें । फिर एक case
या if
- लिखें else
, जिसमें फ़ंक्शन को एक शाखा पर पुनर्निर्देशन और दूसरे पर इसके बिना कहा जाता है।
यदि आप अपने कमांड को उस कोड के रूप में अवधारणा बनाते हैं जिसे आप एक बार लिखना चाहते हैं लेकिन कई परिस्थितियों में चलाते हैं, तो एक फ़ंक्शन प्राकृतिक समाधान है। यह वही है जो मैं आमतौर पर करता हूं। इसमें न तो सबस्क्रिप्शन की जरूरत है और न ही मैनुअल स्टोरेज और स्टेट को रीसेट करने की।
आपके कोड के साथ:
launch() {
google-chrome --headless --disable-gpu --dump-dom \
"$RobWebAddress" > "$DownloadName"
}
case $fCron in
true) launch 2>/dev/null;;
*) launch;; # Get silly error messages when running from terminal
esac
यदि आप चाहें, तो आप जो चाहें, या if
- जैसे चाहें रिक्ति लागू कर सकते else
हैं। ध्यान दें कि launch
स्वचालित रूप से कॉलर RobWebAddress
और DownloadName
चर का उपयोग करता है , भले ही वे स्थानीय चर हों, क्योंकि बैश गतिशील रूप से सबसे प्रोग्रामिंग भाषाओं के विपरीत, जो लेक्सिक रूप से स्कोप हैं।
एक सब-कमांड में कमांड चलाएँ और सशर्त रूप से पुनर्निर्देशन लागू करें exec
। यह क्या है के बारे में टिप्पणी की steeldriver , लेकिन अंदर (
)
प्रभाव स्थानीय रखने के लिए । जब builtin कोई तर्क के साथ चलाया जाता है, यह एक नई प्रक्रिया के साथ वर्तमान खोल को प्रतिस्थापित नहीं करता, लेकिन इसके बजाय मौजूदा खोल करने के लिए अपने पुनर्निर्देशन के किसी भी लागू होता है।exec
(यह भी संभव है कि मानक त्रुटि क्या थी, इसे ट्रैक रखना और इसे फिर से स्थापित करना, बिना सबस्क्रिप्शन का उपयोग किए और इस प्रकार वर्तमान शेल के वातावरण को संशोधित करने की क्षमता का त्याग किए बिना। मैं उस विवरण को अन्य उत्तरों पर छोड़ दूंगा, हालांकि।)
आपके कोड के साथ:
(
# Suppress silly error messages unless running from terminal
case $fCron in true) exec 2>/dev/null;; esac
google-chrome --headless --disable-gpu --dump-dom \
"$RobWebAddress" > "$DownloadName"
)
समापन के बाद )
, मानक त्रुटि प्रभाव में है जो कुछ भी पहले था, क्योंकि यह वास्तव में केवल उपधारा में पुनर्निर्देशित किया जा रहा है, और मूल शेल में नहीं। यह, मौजूदा शेल वेरिएबल्स के साथ भी ठीक काम करता है, क्योंकि सबस्क्रिप्शन वालों को इसकी एक कॉपी मिलती है। हालांकि मैं एक शेल फ़ंक्शन का उपयोग करना पसंद करता हूं, मैं मानता हूं कि इस विधि को कम कोड की आवश्यकता हो सकती है।
दोनों पद्धतियाँ इस बात पर ध्यान दिए बिना काम करती हैं कि फ़ाइल या डिवाइस मानक त्रुटि क्या है, जिसमें शेल कार्यों पर लागू पुनर्निर्देशन के मामले शामिल हैं, जो उस कोड को कहते हैं जिसमें सशर्त व्यवहार होता है, साथ ही मामला (आपके संपादन में उल्लिखित) जिसमें मानक त्रुटि होती है संपूर्ण स्क्रिप्ट पहले से ही पहले से पुनर्निर्देशित हो चुकी है या । पथ प्रतिस्थापन प्रक्रिया प्रतिस्थापन द्वारा उत्पादित किया गया था कोई समस्या नहीं है।exec 2>&fd
exec 2> path
[[ $fCron == true ]] && exec 2>/dev/null
इसके बजाय कोशिश कर सकते हैं