为什么在提供文件路径时不能使用“ ~ ”而不是“ /home/username/ ”

为什么在提供文件路径时不能使用“ ~ ”而不是“ /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/来指向文件路径?

你能详细告诉我吗?

答案1

您需要了解,~shell 通常会扩展它;您调用的程序永远看不到它,它们看到的是 bash 插入的完整路径名。但这仅当波浪号位于参数开头(且未加引号)时才会发生。

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

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

在您自己的代码中,您可以使用getoptargparse进行参数处理,也可以按照@JacobVlijm 的回答所建议的那样手动扩展波浪号。

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

答案2

Python 中的波浪符号扩展

答案很简单:

~除非您使用以下命令,否则python 不会扩展:

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

也可以看看这里

os.path.expanduser(路径)
在 Unix 和 Windows 上,返回以 ~ 或 ~user 为初始组件的参数,并将其替换为该用户的主目录。

在 Unix 上,如果设置了环境变量 HOME,则以 ~ 开头的字符替换该变量;否则,将通过内置模块 pwd 在密码目录中查找当前用户的主目录。将直接在密码目录中查找以 ~user 开头的字符。

答案3

波浪号扩展仅在少数情况下进行,且在不同的 shell 中略有不同

虽然它在以下情况下执行:

var=~

或者

export var=~

在一些 shell 中。它不在

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

在 POSIX shell 中。

bash但是当不处于 POSIX 符合模式时(例如当被调用为shPOSIXLY_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 中你需要引用变量扩展!

答案4

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

立即修复的方法是使用$HOMEshell 变量,它遵循常规变量扩展规则:

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

相关内容