फ़ाइल पथ देते समय मैं '/' के बजाय '/' का उपयोग क्यों नहीं कर सका?


43

मैं फ़ाइल पथ को इंगित करने के ~बजाय उपयोग कर सकता हूं /home/username/, उदाहरण के लिए, .zipफ़ाइल को खोलना ।

हालांकि, आज जब मैंने टर्मिनल में आरएनएन उदाहरण को चलाने के लिए उसी तरह का पालन किया, tensorflow.python.framework.errors_impl.NotFoundErrorतो फेंक दिया गया।

$ python ptb_word_lm.py --data_path=~/anaconda2/lib/python2.7/site-packages/tensorflow/models-master/tutorials/rnn/simple-examples/data/ --model=small 
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcublas.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcudnn.so.5 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcufft.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcurand.so.8.0 locally
Traceback (most recent call last):
  File "ptb_word_lm.py", line 374, in <module>
    tf.app.run()
  File "/home/hok/anaconda2/lib/python2.7/site-packages/tensorflow/python/platform/app.py", line 44, in run
    _sys.exit(main(_sys.argv[:1] + flags_passthrough))
  File "ptb_word_lm.py", line 321, in main
    raw_data = reader.ptb_raw_data(FLAGS.data_path)
  File "/home/hok/anaconda2/lib/python2.7/site-packages/tensorflow/models-master/tutorials/rnn/ptb/reader.py", line 73, in ptb_raw_data
    word_to_id = _build_vocab(train_path)
  File "/home/hok/anaconda2/lib/python2.7/site-packages/tensorflow/models-master/tutorials/rnn/ptb/reader.py", line 34, in _build_vocab
    data = _read_words(filename)
  File "/home/hok/anaconda2/lib/python2.7/site-packages/tensorflow/models-master/tutorials/rnn/ptb/reader.py", line 30, in _read_words
    return f.read().decode("utf-8").replace("\n", "<eos>").split()
  File "/home/hok/anaconda2/lib/python2.7/site-packages/tensorflow/python/lib/io/file_io.py", line 106, in read
    self._preread_check()
  File "/home/hok/anaconda2/lib/python2.7/site-packages/tensorflow/python/lib/io/file_io.py", line 73, in _preread_check
    compat.as_bytes(self.__name), 1024 * 512, status)
  File "/home/hok/anaconda2/lib/python2.7/contextlib.py", line 24, in __exit__
    self.gen.next()
  File "/home/hok/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/errors_impl.py", line 469, in raise_exception_on_not_ok_status
    pywrap_tensorflow.TF_GetCode(status))
tensorflow.python.framework.errors_impl.NotFoundError: ~/anaconda2/lib/python2.7/site-packages/tensorflow/models-master/tutorials/rnn/simple-examples/data/ptb.train.txt

फिर मैंने ~साथ दिया /home/username/, और इसने ठीक से काम किया।

RNN उदाहरण चलाते समय फ़ाइल पथ को इंगित करने के ~बजाय मैं इसका उपयोग क्यों नहीं कर सका /home/username/?

क्या आप मुझे विस्तार से बता सकते हैं?




@ ऑस्करस्कॉग ~को तर्क का विस्तार करने से पहले शेल का विस्तार नहीं करना चाहिए ? जैसे शेल पथ में बैकस्लैश एस्केप का विस्तार करेगा, या यदि पथ उद्धृत किया गया था तो उद्धरण हटा दें।
माइकल जॉनसन

1
इसके विपरीत $VARIABLES, ~केवल एक स्ट्रिंग की शुरुआत में विस्तारित किया जाता है।
एलेक्सिस

@OskarSkog, "पायथन को पता नहीं है कि ~ का क्या अर्थ है" का अर्थ है कि एक मुद्दा अजगर के लिए विशिष्ट है जिसमें कार्यक्षमता का एक टुकड़ा है, एक अनुचित उम्मीद की स्थापना है कि इस तरह की कार्यक्षमता ( डी होने के बाद विस्तार का प्रदर्शन exec) यूनिक्स उपकरणों में व्यापक रूप से उपलब्ध होना चाहिए
चार्ल्स डफी

जवाबों:


45

आपको यह समझने की आवश्यकता है कि ~शेल द्वारा सामान्य रूप से विस्तार किया गया है; आप जिन कार्यक्रमों को कहते हैं, वे इसे कभी नहीं देखते हैं, वे पूरी तरह से देखते हैं। लेकिन यह केवल तब होता है जब टिल्ड एक तर्क की शुरुआत में होता है (और उद्धृत नहीं किया जाता है)।

यदि आप जिस पायथन प्रोग्राम को चला रहे हैं getopt, उसके कमांडलाइन को पार्स करने के लिए एक मॉड्यूल का उपयोग करता है , तो आप --data-pathटिल्ड के विस्तार की अनुमति देने के लिए एक अलग "शब्द" के रूप में विकल्प का तर्क दे सकते हैं :

$ python ptb_word_lm.py --data_path ~/anaconda2/lib/python2.7/...

अपने स्वयं के कोड में, आप तर्क प्रसंस्करण के लिए getoptया उपयोग कर सकते हैं argparse, और मैन्युअल रूप से @ याकूबविल्जम के सुझाव के अनुसार टिल्ड का विस्तार भी कर सकते हैं।

पुनश्च। टिल्ड को शेल चर असाइनमेंट अभिव्यक्ति की शुरुआत में भी विस्तारित किया जाता है जैसे DIRNAME=~/anaconda2; हालाँकि आपके प्रश्न में टिल्ड एक समान चिन्ह का अनुसरण करता है, लेकिन शेल के लिए इस उपयोग का कोई विशेष अर्थ नहीं है (यह सिर्फ एक कार्यक्रम के लिए दिया गया कुछ है) और विस्तार को ट्रिगर नहीं करता है।


6
जब तक आप पहले से ही नहीं जानते getopt , argparseयदि आप पायथन लिख रहे हैं , तो उपयोग करें ।
निक टी

मैंने argparseउत्तर के लिए जोड़ा है क्योंकि यह मुख्य विकल्प है, लेकिन व्यक्तिगत रूप से मुझे इसका उपयोग करना कठिन लगता है getopt, आसान नहीं। YMMV।
एलेक्सिस

33

अजगर में टिल्ड का विस्तार

उत्तर छोटा और सरल है:

~जब तक आप उपयोग नहीं करते अजगर का विस्तार नहीं होता है :

import os
os.path.expanduser('~/your_directory')

यहाँ भी देखें :

os.path.expanduser (पथ)
यूनिक्स और विंडोज पर, उस उपयोगकर्ता के घर निर्देशिका द्वारा प्रतिस्थापित ~ या ~ उपयोगकर्ता के प्रारंभिक घटक के साथ तर्क लौटाएं।

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


11
सामान्य तौर पर, आपको यह कभी नहीं मानना ​​चाहिए कि ओएस स्तर पर टिल्ड का विस्तार किया जाता है, यह कुछ ऐसा है जो यूनिक्स के गोले (और उनमें से सभी नहीं!) आपके लिए करते हैं।
फ़ारसिल

1
मुझे लगता है कि एलेक्सिस के उत्तर में अधिक प्रासंगिक मुद्दा पंक्तिबद्ध है: ~शेल तर्क सूची में स्थिति ।
डेविड फ़ॉस्टर 01

@farsil, मैं असहमत हूं। प्रोग्राम को पोर्टेबल बनाया जा सकता है, लेकिन जब आप उन्हें कमांड लाइन से चलाते हैं, तो आप एक विशिष्ट सिस्टम पर ऐसा करते हैं। और यह मत भूलिए कि यह askubuntu.com है, और उबंटू हमेशा यूनिक्स है ( जहाँ तक हम जानते हैं :-)
एलेक्सिस

1
@alexis: उबंटू ओएस स्तर पर टिल्ड विस्तार नहीं करता है। यह अभी भी शेल कार्यक्षमता है।
user2357112

1
मिथिंक्स आप बालों को विभाजित कर रहे हैं। किसी ने नहीं कहा कि कर्नेल कर रहा है। मुद्दा यह है, यह उस कार्यक्रम द्वारा नहीं किया जाता है जो तर्क लेता है।
एलेक्सिस

12

टिल्ड का विस्तार केवल कुछ संदर्भों में किया जाता है जो गोले के बीच थोड़ा भिन्न होता है

जबकि यह प्रदर्शन किया गया है:

var=~

या

export var=~

कुछ गोले में। यह अंदर नहीं है

echo var=~
env var=~ cmd
./configure --prefix=~

POSIX गोले में।

bashहालांकि यह तब है जब POSIX अनुरूपता मोड में नहीं है (जैसे कि जब कहा जाता है sh, या जब POSIXLY_CORRECTपर्यावरण में होता है):

$ bash -c 'echo a=~'
a=/home/stephane
$ POSIXLY_CORRECT= bash -c 'echo a=~'
a=~
$ SHELLOPTS=posix bash -c 'echo a=~'
a=~
$ (exec -a sh bash -c 'echo a=~')
a=~

हालाँकि यह केवल तभी है जब बाईं ओर बाईं ओर =एक अयोग्य वैध चर नाम की तरह आकार दिया गया है, इसलिए जब इसका विस्तार किया जाएगा, तो यह अंदर cmd prefix=~नहीं होगा cmd --prefix=~(जैसा --prefixकि एक वैध चर नाम नहीं है) और न ही cmd "p"refix=~(उस उद्धृत के कारण p) और न ही में है var=prefix; cmd $var=~

में zsh, आप किसी भी निर्विवाद के बाद विस्तार के magic_equal_substलिए विकल्प निर्धारित कर सकते हैं ।~=

$ zsh -c 'echo a=~'
a=~
$ zsh -o magic_equal_subst -c 'echo a=~'
a=/home/stephane
$ zsh -o magic_equal_subst -c 'echo --a=~'
--a=/home/stephane

~(के विपरीत ~user) के मामले में , आप $HOMEइसके बजाय बस का उपयोग कर सकते हैं :

cmd --whatever="$HOME/whatever"

~के मान तक फैलता है $HOME। यदि $HOMEसेट नहीं किया गया है, तो व्यवहार गोले के बीच भिन्न होता है। कुछ शेल उपयोगकर्ता डेटाबेस को क्वेरी करते हैं। यदि आप इसे ध्यान में रखना चाहते हैं, तो आप कर सकते हैं (और यह भी कि आपको इसके लिए क्या करना होगा ~user):

dir=~ # or dir=~user
cmd --whatever="$dir/whatever"

किसी भी मामले में, गोले के अलावा zshआपको याद रखने की ज़रूरत है कि चर विस्तार क्या है!


1
बाश के संदर्भ मैनुअल में कहा गया है कि टिल्ड्स का विस्तार केवल चर असाइनमेंट और एक शब्द की शुरुआत में किया जाता है, इसलिए इसका विस्तार करने पर यह echo a=~मैनुअल के विपरीत लगता है।
लक्कू

@ilkachachu, हां मैनुअल अधूरा है। यह भी स्पष्ट रूप से निर्दिष्ट नहीं करता है कि किस संदर्भ में ~विस्तार किया जाएगा ("शब्द" का क्या अर्थ है)। अधिक विवरण के लिए उत्तर के शीर्ष पर स्थित लिंक देखें।
स्टीफन चेज़लस

6

~विशेष विस्तार नियम हैं, जिन्हें आपकी कमांड संतुष्ट नहीं करती है। विशेष रूप से, इसका विस्तार केवल तब किया जाता है, जब किसी शब्द की शुरुआत में (जैसे python ~/script.py) या एक चर असाइनमेंट (जैसे PYTHONPATH=~/scripts python script.py) की शुरुआत में । आपके पास --data_path=~/blablaजो है वह शेल शब्दों में एकल शब्द है, इसलिए विस्तार नहीं किया जाता है।

$HOMEशेल चर का उपयोग करने के लिए एक तत्काल सुधार है , जो नियमित चर विस्तार नियमों का पालन करता है:

python ptb_word_lm.py --data_path=$HOME/blabla

यह एक सा ओवरसाइम्प्लीफाइड है, अन्य संदर्भ हैं जैसे टिल्ड का विस्तार किया जाता है PATH=$PATH:~/bin। इसके अलावा, जिसे $HOMEखोलना या विभाजित करना होगा + ग्लोब इसके अलावा गोले में लागू होता है zsh
स्टीफन चेज़लस

@sch क्षमा करें, लेकिन आपके द्वारा टिप्पणी में प्रदान किया गया लिंक ऑप्टिकल माउस के बारे में एक प्रश्न है, जिसमें टिल्ड विस्तार का कोई उल्लेख नहीं है। आप कृपया समझा सकते हैं?
सर्गी कोलोडियाज़नी

अच्छा उत्तर। यह मूल रूप से संक्षेप bashमें बताता है कि Tilde Expansionअनुभाग में क्या मैनुअल बताता है । +1
सर्गि कोलोदज़हनी

क्षमा करें, मुझे यूनिक्स में इंट्रा-साइट लिंक का उपयोग करने के लिए उपयोग किया जाता है। जैसा [link](/a/146697)कि मुझे पता नहीं था कि हम यहां एक अलग साइट पर थे। लिंक वहाँ
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.