मैं उद्धृत टिल्ड ('~') को सीडी क्यों नहीं दे सकता?


32

मेरी पहली स्क्रिप्ट लिखना तो मुझे यकीन है कि यह एक बुनियादी सवाल है, लेकिन क्या कोई मुझे समझा सकता है कि मैं क्यों कर सकता हूं:

cd ~
cd bin
cd ~/bin
cd 'bin'

लेकिन नहीं

cd '~'
cd '~/bin'

मुझे cdनिर्देशिका नामों में से एक में एक स्थान के साथ एक निर्देशिका पथ की आवश्यकता है, इसलिए मुझे उद्धरण (यह Program Filesशराब के तहत विंडोज है ) की आवश्यकता है। मैं इसे दो cdआदेशों के साथ प्राप्त कर सकता हूं , लेकिन मैं ~उद्धरणों में क्यों नहीं डाल सकता हूं ?

यदि मैं टाइप cd '~'(या cd "~") मैं मिलता है:

bash: cd: ~: No such file or directory

29
अपने आप से यह पूछें: अगर वह इस तरह से काम नहीं करता है, तो आप cdएक निर्देशिका में कैसे नाम देंगे ~?
जोर्ग डब्ल्यू मित्तग

2
एक विचार के रूप में, यदि आप एक स्क्रिप्ट लिख रहे हैं तो आपको पूर्ण पथ का उपयोग करना चाहिए और पूरी तरह से बचना cdचाहिए। उन चरनामों को संग्रहीत करने के लिए चर का उपयोग करें जिन्हें आप कई बार टाइप नहीं करना चाहते हैं, जैसेpf=~/.wine/drive_c/Program\ Files/; cp /path/to/file "$pf"
मिठाई

8
@jamesqf: क्यों एक समझदार प्रणाली मुझे मेरी फ़ाइलों और निर्देशिकाओं का नाम देना चाहती है, इससे बेहतर जानने के लिए क्या होगा? इसके अलावा, मुझे यह कभी समझ में नहीं आया कि यूनिक्स पथ घटक विभाजकों और पथ टर्मिनलों के मैजिक इन-बैंड सिग्नलिंग के साथ क्यों गया। एक फ़ाइल / निर्देशिका नाम /या क्या गलत है NUL?
जोर्ग डब्ल्यू मित्तग

3
@ JörgWMittag संभवतःcd ./~
k_g

2
@jamesqf ऐतिहासिक रूप से ध्यान देने योग्य है कि, यूनिक्स फाइलसिस्टम ने '/' (पथ विभाजक) और '\ 0' (NUL - स्ट्रिंग-टर्मिनेशन चार) को छोड़कर किसी भी फ़ाइल नाम में चार वर्णों को Jorg नोट के रूप में अनुमति दी है। अन्य कोई प्रतिबंध नहीं। कई यूनिक्स फाइल सिस्टम कार्यान्वयन हुए हैं, इसलिए उनमें से किसी एक में प्रतिबंधों का परिचय देने से संगतता टूट जाएगी और जटिलता बढ़ जाएगी - और "अजीब" के रूप में देखा गया है! और '~' विस्तार केवल तुलनात्मक रूप से हाल ही में csh और अधिक व्यापक रूप से bash में पेश किया गया था, '~' वर्णों वाली फाइलें / डायर अज्ञात नहीं हैं (उदाहरण के लिए myfile ~ myfile के लिए बैकअप के रूप में)।
सुसैन

जवाबों:


78

जैसा कि @karel ने अपने जवाब में कहा, ~एक विशेष चरित्र है और वर्तमान उपयोगकर्ता के होम डायरेक्टरी में बैश द्वारा विस्तारित किया गया है। "टिल्ड एक्सपेंशन" पर बैश मैनुअल देखें , या मैन पेज में हेडलाइन "टिल्ड एक्सपेंशन" की खोज करें ( man bash)।

~इस टिल्ड के विस्तार को रोकता है।


आपके प्रश्न का उत्तर देने के लिए कि आप अभी भी इसका उपयोग cdनिर्देशिका में इसके नाम के साथ कैसे कर सकते हैं , इसके कुछ विकल्प हैं:

  • ओमिट उद्धरण और इसके बजाय बैकस्लैश के साथ रिक्त स्थान से बाहर निकलें:

    cd ~/foo/spaces\ are\ cool/bar
  • शेष पथ को उद्धृत करें, लेकिन उन्हें टिल्ड और पहली स्लैश के चारों ओर छोड़ दें:

    cd ~/"foo/spaces are cool/bar"

    जैसा कि आप देखते हैं, आप बस के बीच में बिना किसी रिक्त स्थान के एक-दूसरे के बगल में लिखकर बैश में उद्धृत और अयोग्य तार को समतल कर सकते हैं।

  • $HOMEटिल्ड के बजाय पर्यावरण चर का उपयोग करें , जो अभी भी "दोहरे उद्धरण" (लेकिन 'एकल उद्धरण' नहीं) के अंदर विस्तारित होता है:

    cd "$HOME/foo/spaces are cool/bar"

3
@rexkogitans ~'/...'काम नहीं करेगा और न ही इस उत्तर में क्या है। ~/'...'या ~/"..."काम करेगा।
HVD

tld; dr: क्योंकि दैट्स शैल सिंटैक्स
सर्जि कोलोडियाज़नी

@hvd धन्यवाद फिक्स्ड टाइपो। यह सबसे पूर्ण उत्तर है और यह भी बताता है कि ओपी क्या करना चाहता है। ~/'path'जाने का रास्ता है।
रेक्सोगाइट्स

1
@ जिज्ञासा से थोड़ा कम, ~'/...'काम क्यों नहीं करेगा ? स्लैश एक विशेष चरित्र नहीं है, इसलिए ऐसा लगता है कि इसे उद्धरण के अंदर या बाहर काम करना चाहिए।
कोडोस जॉनसन

6
@KodosJohnson "Tilde Expansion" के बारे में बैश मैनपेज के अनुभाग पर एक नज़र डालें। उस के प्रासंगिक पैराग्राफ को नीचे मिठाई के उत्तर में भी उद्धृत किया गया है। टीएल; डीआर: टिल्ड का विस्तार होता है यदि किसी शब्द में पहला चरित्र एक अनछुए टिल्ड है, तो उस टिल्ड और अगले अनक्लोस्ड स्लैश के बीच का सब कुछ "टिल्ड प्रीफ़िक्स" माना जाता है। यदि यह उपसर्ग +, -, संख्या, या उपयोगकर्ता नाम (वहां उद्धरण की अनुमति नहीं है) जैसी मान्य चीज नहीं है, तो विस्तार विफल हो जाता है और आपको एक शाब्दिक ~ चरित्र मिल जाता है।
बाइट कमांडर

17

~ एक विशेष चरित्र है जिसे शेल द्वारा उपयोगकर्ता के घर निर्देशिका में लॉग के रूप में व्याख्या किया गया है। '~' को शेल द्वारा शाब्दिक ~ चरित्र के रूप में व्याख्यायित किया जाता है, उपयोगकर्ता की घरेलू निर्देशिका में लॉग इन के रूप में नहीं क्योंकि दो एकल उद्धरण वर्णों के अंदर एक स्ट्रिंग संलग्न करने से उस स्ट्रिंग में शाब्दिक पाठ स्ट्रिंग के रूप में व्याख्या की जाती है।


~इस अर्थ में एक उपनाम नहीं है जो bashइसकी व्याख्या करता है: उपनाम एक स्ट्रिंग को एक शब्द के लिए प्रतिस्थापित करने की अनुमति देता है जब इसे एक साधारण कमांड के पहले शब्द के रूप में उपयोग किया जाता है। । जैसा कि मैं नीचे अपने उत्तर में समझाता हूं, यह एक विस्तार है।
मिठाई

15

यह एक bashफीचर है जिसे टिल्ड एक्सपेंशन कहा जाता है । उद्धृत man bash:

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

कार्य के विस्तार के लिए टिल्ड चरित्र ~को निर्विवादित करने की आवश्यकता होती है, अन्यथा चरित्र को अक्षरशः लिया जाता है और cdयदि ~वर्तमान निर्देशिका में कोई निर्देशिका मौजूद नहीं है तो वह विफल हो जाता है । में उद्धृत करने के स्पष्टीकरण के लिए इस मोहक उत्तर को देखें bash। यदि आपको पथ का हिस्सा उद्धृत करने की आवश्यकता है, तो आप निम्न कर सकते हैं:

  1. कम से कम पात्रों को उद्धृत करें, जिन्हें एकल उद्धरण के साथ उद्धृत करने की आवश्यकता है, जैसे

    ~/dir' 'with' 'spaces/

    या

    ~/'dir with spaces/'
  2. कम से कम पात्रों को उद्धृत करें, जिन्हें दोहरे उद्धरण चिह्नों के साथ उद्धृत करने की आवश्यकता है, जैसे

    ~/dir" "with" "spaces/

    या

    ~/"dir with spaces/"
  3. केवल उन वर्णों को उद्धृत करें जिन्हें बैकस्लैश के साथ उद्धृत करने की आवश्यकता है, जैसे

    ~/dir\ with\ spaces/

टिल्ड विस्तार में कुछ और दिलचस्प विशेषताएं हैं, जैसे:

  • ~+के मान तक फैलता है PWD, अर्थात वर्तमान कार्यशील निर्देशिका
  • ~-के मान तक फैलता है OLDPWD, अर्थात पिछली कार्यशील निर्देशिका
  • ~john लॉगिन नाम "जॉन" के साथ जुड़े होम निर्देशिका में फैलता है

संयोग से, बैकस्लैश के साथ 'ओवरक्लोट' करना भी ठीक है; जैसे, $ touch a; cd \a। (मुझे लगा कि इससे परेशानी हो सकती है cd \n, लेकिन कम से कम मेरे संस्करण पर प्रयोग से bashयह पता चलता है कि यह ठीक काम करता है।)
एलएसपीस

1

echoकमांड का उपयोग करके अन्वेषण करें

यह जानने का सबसे आसान तरीका है कि echoकमांड में चीजों को कैसे काम किया जाता है । ~इस उपयोग के मामले में :

$ echo ~
/home/rick
$ echo '~'
~
$ echo "~"
~
$ echo `~`
bash: /home/rick: Is a directory

जैसा कि आप देख सकते हैं, जब आप एकल उद्धरण या ~इसके चारों ओर दोहरे उद्धरणों का उपयोग करते हैं, तो इसका शाब्दिक अर्थ है एक स्ट्रिंग के रूप में और एक चर के रूप में विस्तारित नहीं। जब आप backticks (`) का उपयोग करते हैं तो इसे कमांड के रूप में निष्पादित किया जाता है और एक त्रुटि संदेश उत्पन्न करता है।

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