बैश चर का उपयोग करके निर्देशिका में जाने से काम नहीं होता है जब निर्देशिका के नाम में स्थान होता है


11

मान लीजिए कि मैं निम्नलिखित कमांड को एक चर में संग्रहीत करना चाहता हूं

cd "/cygdrive/c/Program Files/"

इसलिए मैं ऐसा करता हूं

dir="cd \"/cygdrive/c/Program Files/\""

प्रोग्राम फ़ाइल निर्देशिका में नेविगेट करने के लिए कमांड को स्टोर करना चाहिए, इसलिए जब मैं $ dir टाइप करता हूं तो यह मुझे उस निर्देशिका में ले जाता है। यह जांचने के लिए कि कोटेशन ठीक से बच गया है, मैं टाइप करता हूं

echo $dir

जो मुझे देता है

cd "/cygdrive/c/Program Files/"

तो सब कुछ ठीक काम करना चाहिए। हालाँकि, जब मैं टाइप करता हूँ,

$dir

मुझे मिला

bash: cd: "/cygdrive/c/Program: No such file or directory

मैं क्या गलत कर रहा हूं? मैं Cygwin का उपयोग कर रहा हूं, लेकिन मुझे लगता है कि यह समस्या सामान्य रूप से टकराती है।


निर्देशिका नाम के आसपास के कोट्स को हटाने का प्रयास करें और इसके बजाय बैकस्लैश के साथ अंतरिक्ष से बच जाएं।
माइक फिट्जपैट्रिक

जवाबों:


8

संक्षिप्त उत्तर: BashFAQ # 050 देखें ("मैं एक चर में एक कमांड डालने की कोशिश कर रहा हूं, लेकिन जटिल मामले हमेशा विफल रहते हैं!")।

लंबा उत्तर: जब बैश एक कमांड को पार्स करता है, तो वह चर को बदलने से पहले उद्धरण देता है; यह कभी भी चर के मूल्यों में वापस और फिर से पार्स नहीं करता है, इसलिए वे कुछ भी उपयोगी नहीं करते हैं। कमांड की जांच करने के लिए प्रतिध्वनि का उपयोग करना पूरी तरह से भ्रामक है क्योंकि यह पार्स होने के बाद कमांड को दिखाता है; यदि आप यह देखना चाहते हैं कि वास्तव में निष्पादित किए जा रहे उपयोग के लिए या तो set -xशेल प्रिंट कमांड के रूप में वे निष्पादित हैं, या printf "%q " $dir; echoसादे गूंज के बजाय उपयोग करें ।

यदि आप एक जटिल कमांड को स्टोर करना चाहते हैं (यानी "शब्दों में रिक्त स्थान या अन्य विशेष वर्णों के साथ), तो आपको इसे एक साधारण टेक्स्ट वेरिएबल के बजाय एक सरणी में रखना होगा, और फिर इसे मुहावरे के साथ विस्तारित करना होगा" "$ { सरणी [@]} ", इस तरह:

dir=(cd "/cygdrive/c/Program Files/")
"${dir[@]}"

अब, यदि उद्देश्य एक आसान-से-प्रकार शॉर्टहैंड बनाना है, तो यह स्पष्ट रूप से जाने का तरीका नहीं है। इसके बजाय एक शेल उपनाम या फ़ंक्शन का उपयोग करें:

alias dir='cd "/cygdrive/c/Program Files/"'
dir

या

dir() { cd "/cygdrive/c/Program Files/"; }
dir

7

जब बैश का विस्तार होता है $dir, तो यह केवल शब्द विभाजन और उस पर ग्लोबिंग करता है। पद बंटवारे तीन शब्दों का उत्पादन: cd, "/cygdrive/c/Programऔर Files/"। फिर निष्पादित करने की आज्ञा cdदो तर्कों के साथ है; cdकेवल इसके पहले तर्क को देखता है "/cygdrive/c/Program, जो एक मौजूदा निर्देशिका नहीं है।

यदि आप किसी चर की सामग्री पर पूर्ण शैल मूल्यांकन करना चाहते हैं, तो उपयोग करें eval:

eval "$dir"

ध्यान दें कि आपको दोहरे उद्धरण चिह्नों की आवश्यकता है $dir, अन्यथा शब्द विभाजन पहले किया जाएगा, फिर evalरिक्त स्थान के साथ अपने तर्कों को व्यक्त करेंगे। यह यहां काम करने के लिए होगा, लेकिन सामान्य रूप से खराब होगा (जैसे अगर फ़ाइल नाम में दो लगातार स्थान थे)।

हालाँकि, एक शेल कमांड को स्टोर करने का सही तरीका नहीं है जिसे आप निष्पादित करना चाहते हैं। जब तक आपके पास एक असामान्य आवश्यकता नहीं है, आपको इसके बजाय एक फ़ंक्शन का उपयोग करना चाहिए:

dir () {
  cd "/cygdrive/c/Program Files/"
}

यदि आप वास्तव में $dirकिसी विशेष निर्देशिका पर स्विच करने के लिए टाइपिंग में रुचि रखते हैं और यह केवल एक सरल उदाहरण नहीं है, तो 4 के बाद से, shopt -s autocdअपने .bashrcसेट में डाल दें

dir="/cygdrive/c/Program Files/"

जिसके बाद आप उस निर्देशिका पर स्विच करने के लिए सिर्फ "/cygdrive/c/Program Files/"या "$dir"शेल प्रॉम्प्ट पर टाइप कर सकते हैं । आपको अभी भी दोहरे उद्धरण चिह्नों की आवश्यकता है $dir; यदि आपको वह पसंद नहीं है, तो बैश के बजाय ज़श का उपयोग करें।


6

चर में आदेशों का भंडारण आमतौर पर एक अच्छा विचार नहीं है। यही कार्य और उपनाम हैं।

बजाय

dir="cd \"/cygdrive/c/Program Files/\""

इनमें से एक आज़माएँ:

dir="/cygdrive/c/Program Files"
...
cd "$dir"

या

dir() { cd "/cygdrive/c/Program Files"; }
dir

या

alias dir='cd "/tmp/Program Files"'
...
dir

एक चर में निर्देशिका के नाम को संग्रहीत करने वाला पहला रूप, थोड़ा अधिक टाइपिंग का मतलब है, लेकिन यह स्पष्ट है कि जब आप उस कमांड को निष्पादित करते हैं जो आप कर रहे हैं cd। दूसरा वह निकटतम है जो आप पूरा करने की कोशिश कर रहे हैं। (मैं बैश में बहुत अधिक उपनाम का उपयोग नहीं करता हूं; मुझे वास्तव में यकीन नहीं है कि उनके पास फ़ंक्शंस का क्या फायदा है।)

संपादित करें:

और dirशायद एक उपनाम या फ़ंक्शन के लिए एक बुरा नाम है, क्योंकि उस नाम से एक मौजूदा कमांड है (यह मूल रूप से एक संस्करण है ls, कम से कम यदि आपके पास जीएनयू कोरुटिल है)।


upvote के लिएStoring commands in variables is generally not a good idea. That's what functions and aliases are for.
रॉब

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