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

JNi*_*ing 46 python command-line bash

例如,在解压缩文件时,我可以使用~而不是/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
Run Code Online (Sandbox Code Playgroud)

然后我替换~/home/username/,并且它正常工作。

为什么在运行 RNN 示例时不能使用~而不是/home/username/指向文件路径?

能详细说一下吗?

ale*_*xis 49

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

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

$ python ptb_word_lm.py --data_path ~/anaconda2/lib/python2.7/...
Run Code Online (Sandbox Code Playgroud)

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

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

  • 除非您*知道* `getopt`,如果您正在编写 Python,请使用 [`argparse`](https://docs.python.org/3/library/argparse.html)。 (7认同)

Jac*_*ijm 37

python中的波浪号扩展

答案很简单:

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

import os
os.path.expanduser('~/your_directory')
Run Code Online (Sandbox Code Playgroud)

另见此处

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

在 Unix 上,初始的 ~ 被设置为环境变量 HOME 替换;否则通过内置模块pwd在password目录中查找当前用户的家目录。直接在密码目录中查找初始 ~user。

  • 一般来说,你永远不应该假设波浪号扩展是在操作系统级别完成的,这是 unix shell(而不是所有 shell!)为你做的事情。 (12认同)

Sté*_*las 13

波浪号扩展仅在外壳之间略有不同的少数上下文中进行

虽然它是在:

var=~
Run Code Online (Sandbox Code Playgroud)

或者

export var=~
Run Code Online (Sandbox Code Playgroud)

在一些贝壳中。它不在

echo var=~
env var=~ cmd
./configure --prefix=~
Run Code Online (Sandbox Code Playgroud)

在 POSIX shell 中。

它是在bash不处于 POSIX 一致性模式时(例如调用 as 时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=~
Run Code Online (Sandbox Code Playgroud)

然而,只有当左边的=形状像一个不带引号的有效变量名时,所以当它被扩展时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
Run Code Online (Sandbox Code Playgroud)

~(相对于~user)的情况下,您可以$HOME改为使用:

cmd --whatever="$HOME/whatever"
Run Code Online (Sandbox Code Playgroud)

~扩展到 的值$HOME。如果$HOME未设置,则外壳之间的行为会有所不同。一些 shell 查询用户数据库。如果你想考虑到这一点,你可以这样做(这也是你必须做的~user):

dir=~ # or dir=~user
cmd --whatever="$dir/whatever"
Run Code Online (Sandbox Code Playgroud)

无论如何,在 shell 中,除了zsh记住你需要引用变量扩展!


Dmi*_*yev 7

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

一个直接的解决方法是使用$HOMEshell 变量,它遵循常规的变量扩展规则:

python ptb_word_lm.py --data_path=$HOME/blabla
Run Code Online (Sandbox Code Playgroud)