BIN_DIR = "~ / bin /" वाली स्क्रिप्ट में mkdir विफल (ऐसी कोई फ़ाइल या निर्देशिका) क्यों नहीं है?


10

क्यों mkdir कमांड विफल रहता है: "ऐसी कोई फ़ाइल या निर्देशिका नहीं"?

#!/bin/bash

set -e

BIN_DIR="~/bin/"

if [ ! -d "$BIN_DIR" ]; then
  mkdir "$BIN_DIR"
fi

जवाबों:


11

त्रुटि संदेश का उत्पादन किया जाता है क्योंकि टिल्ड ~को उद्धृत किया जाता है, जैसा कि ज़न्ना के उत्तर में वर्णित है । यदि आप उपयोग करना चाहते हैं ~, तो स्क्रिप्ट का प्रासंगिक हिस्सा होना चाहिए:

BIN_DIR=~/bin/

यदि किसी कारण से आप स्ट्रिंग को उद्धृत करना चाहते हैं, तो आप पर्यावरण चर का उपयोग कर सकते हैं $HOME:

BIN_DIR="$HOME/bin/"

मेरी राय में दूसरा तरीका बेहतर अभ्यास है।


6
~स्क्रिप्ट में उपयोग करने में कुछ भी गलत नहीं है । यह कमांड लाइन की तरह ही काम करता है। समस्या यह है कि ज़न्ना के जवाब में बताया गया है कि ब्लॉक टिल्ड विस्तार का हवाला देते हुए ।
टेराडो

@terdon, मैं सहमत हूँ। लेकिन मैंने नहीं बताया कि कुछ गलत है, लेकिन यह एक बेहतर विचार है, क्योंकि आपको कम ध्यान देना चाहिए।
पा ०४०80०

5
लेकिन यहाँ कमांड लाइन और स्क्रिप्ट के बीच कोई अंतर नहीं है। तथ्य यह है कि यह एक स्क्रिप्ट में है पूरी तरह से अप्रासंगिक है, आपको कमांडलाइन में बिल्कुल वही त्रुटि होगी। मुद्दा उद्धरण है, ऐसा नहीं है कि यह एक स्क्रिप्ट में है।
टेर्डन

जबकि यह पूरी तरह से सच है यह सही है कि $HOMEलिपियों में उपयोग करना एक अच्छा विचार है।
मिठाई

3
@ pa4080 क्या आप इस बात का स्पष्टीकरण जोड़ सकते हैं कि आपको क्यों लगता है कि विस्तार $HOMEसे बेहतर है टिल्ड विस्तार का उपयोग करना? आपके द्वारा दिया गया एकमात्र स्पष्टीकरण यह कहना है, "यह एक बेहतर विचार है, क्योंकि आपको कम ध्यान देना चाहिए।" मुझे उसका मतल नही पाता। क्या आप इसे एक संपादन में उजागर कर सकते हैं? इसके बिना, आपके उत्तर का समर्थन करने के लिए कुछ भी नहीं है, इसलिए निश्चित रूप से इसमें निहित है। POSIX द्वारा अब कुछ समय के लिए Tilde विस्तार की आवश्यकता है और स्क्रिप्ट की हैशबैंग लाइन है #!/bin/bashइसलिए मुझे लगता है कि पोर्टेबिलिटी इसका कारण नहीं है।
एलियाह कगन

23

~उद्धृत होने के कारण यह काम नहीं करता है। डबल उद्धरण टिल्ड विस्तार को" दबाते हैं । शाब्दिक नाम के साथ कोई निर्देशिका नहीं है । के रूप में समझाया (जोर मेरा):~/binman bash

टिल्ड विस्तार

यदि कोई शब्द एक अनछुए टिल्ड वर्ण (`~ ') के साथ शुरू होता है , तो पहले निर्विवाद स्लैश (या यदि कोई अयोग्य स्लैश नहीं है) से पहले के सभी वर्ण टिल्ड-प्रीफ़िक्स माने जाते हैं। यदि टिल्ड-प्रीफ़िक्स में कोई भी वर्ण उद्धृत नहीं किया जाता है, तो टिल्ड के बाद वाले टिल्ड-प्रीफ़िक्स के पात्रों को एक संभावित लॉगिन नाम के रूप में माना जाता है। यदि यह लॉगिन नाम नल स्ट्रिंग है, तो शेल पैरामीटर होम के मान के साथ टिल्ड को बदल दिया जाता है। यदि घर परेशान है, तो शेल को निष्पादित करने वाले उपयोगकर्ता की होम निर्देशिका को इसके बजाय प्रतिस्थापित किया जाता है। अन्यथा, टिल्ड-प्रीफ़िक्स को निर्दिष्ट लॉगिन नाम के साथ जुड़े होम डायरेक्टरी से बदल दिया जाता है।

आप उद्धरणों को हटा सकते हैं , क्योंकि ~पथ में एकमात्र चरित्र ~/binहै जो शेल को विस्तार करने का कारण होगा, और हम इस मामले में विस्तार चाहते हैं। शेल टिल्ड विस्तार के परिणाम पर कोई और विस्तार नहीं करेगा , कम से कम बाश 4 में , जो उबंटू के सभी वर्तमान या दूरस्थ रूप से हालिया रिलीज़ हैं । यहां तक ​​कि अगर आपके घर निर्देशिका में रिक्त स्थान जैसे असामान्य वर्ण हैं, तो भी यह ठीक है।

या आप उपयोग कर सकते हैं $HOMEबजाय की ~, क्योंकि पैरामीटर विस्तार केवल द्वारा, डबल कोट द्वारा दबा नहीं है एकल उद्धरण । दोहरे उद्धरण यह सुनिश्चित करते हैं कि विस्तारित मूल्य स्वयं किसी भी आगे के विस्तार के अधीन नहीं है, इसलिए शब्द विभाजन या फ़ाइल नाम विस्तार नहीं होगा। तो $HOMEअजीब तरह से घर निर्देशिकाओं के नाम के साथ भी काम करता है, इसलिए, जब तक आप दोहरे उद्धरण चिह्नों को रखते हैं।


इस कथन के अनुसार "पैरामीटर विस्तार केवल दोहरे उद्धरण द्वारा दबाया नहीं जाता है, केवल" : का आउटपुट cd '~'है -bash: cd: ~: No such file or directory
पा ०४०80०

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