当前位置: 首页>>技术教程>>正文


在给出文件路径时,为什么我不能使用’〜’而不是’/home/username/’

, , ,

问题描述

我可以使用~而不是/home/username/指向文件路径,例如,解压缩.zip文件。

然而,今天当我按照相同的方式在终端中运行RNN示例时,抛出了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/指向文件路径?

你能详细告诉我一下吗?

最佳解决办法

您需要了解~通常由shell扩展;你调用的程序永远不会看到它,它们会看到bash插入的完整路径名。但这只发生在波浪号在参数开始时(并且没有引用)。

如果您运行的Python程序使用类似getopt的模块来解析其命令行,则可以将--data-path选项的参数作为单独的”word”给出以允许波浪形扩展:

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

在您自己的代码中,您可以使用getoptargparse进行参数处理,也可以手动扩展波浪线,如@ JacobVlijm的答案所示。

PS。 tilde也在shell变量赋值表达式的开头扩展,如DIRNAME=~/anaconda2;虽然你的问题中的波浪号也遵循等号,但这种用法对shell没有特殊意义(它只是传递给程序的东西)并且不会触发扩展。

次佳解决办法

python中的Tilde扩展

答案很简短&简单:

python不会扩展~,除非您使用:

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

另见here

os.path.expanduser(path)
On Unix and Windows, return the argument with an initial component of ~ or ~user replaced by that user‘s home directory.

On Unix, an initial ~ is replaced by the environment variable HOME if it is set; otherwise the current user’s home directory is looked up in the password directory through the built-in module pwd. An initial ~user is looked up directly in the password directory.

第三种解决办法

Tilde expansion is only done in a few contexts that vary slightly between shells

虽然它是在:

var=~

要么

export var=~

在一些炮弹。它不在

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

在POSIX shell中。

它在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,则shell之间的行为会有所不同。一些shell查询用户数据库。如果你想考虑到这一点,你可以做(​​这也是你必须为~user做的事情):

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

在任何情况下,在zsh以外的shell中记住你需要引用变量扩展!

第四种办法

~具有特定的扩展规则,您的命令不满足。具体地说,它仅在未加引号时扩展,或者在单词的开头(例如python ~/script.py)或者在变量赋值的开头(例如PYTHONPATH=~/scripts python script.py)。您所拥有的是--data_path=~/blabla,这是shell中的单个单词,因此不执行扩展。

立即修复是使用$HOME shell变量,它遵循常规变量扩展规则:

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

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/1804.html,未经允许,请勿转载。