10 hours ago
I can use ~ instead of /home/username/ to point to a file path when, for example, unzipping a .zip file.
~
/home/username/
.zip
However, today when I followed the same way to run a RNN example in terminal, tensorflow.python.framework.errors_impl.NotFoundError was thrown.
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
Then I replaced ~ with /home/username/, and it worked properly.
Why couldn't I use ~ instead of /home/username/ to point to the file path when runing a RNN example?
Could you tell me in detail?
35 hours ago
You need to understand that ~ is normally expanded by the shell; the programs you call never see it, they see the full pathname as inserted by bash. But this only happens when the tilde is at the start of an argument (and is not quoted).
If the Python program you are running uses a module like getopt to parse its commandline, you can give the argument of the --data-path option as a separate "word" to allow tilde expansion:
getopt
--data-path
$ python ptb_word_lm.py --data_path ~/anaconda2/lib/python2.7/...
In your own code, you can use getopt or argparse for argument processing, and could also manually expand tildes as @JacobVlijm's answer suggested.
argparse
PS. The tilde is also expanded at the start of a shell variable assignment expression like DIRNAME=~/anaconda2; although the tilde in your question also follows an equals sign, this usage doesn't have special meaning for the shell (it's just something passed to a program) and doesn't trigger expansion.
DIRNAME=~/anaconda2
8 hours ago
The answer is short & simple:
python does not expand ~ unless you use:
import os os.path.expanduser('~/your_directory')
See also 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.
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.
15 hours ago
Tilde expansion is only done in a few contexts that vary slightly between shells.
While it is performed in:
var=~
Or
export var=~
in some shells. It's not in
echo var=~ env var=~ cmd ./configure --prefix=~
in POSIX shells.
It is in bash though when not in POSIX conformance mode (like when called as sh, or when POSIXLY_CORRECT is in the environment):
bash
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=~
However that's only when what's on the left of the = is shaped like an unquoted valid variable name, so while it would be expanded in cmd prefix=~, it would not be in cmd --prefix=~ (as --prefix is not a valid variable name) nor in cmd "p"refix=~ (because of that quoted p) nor in var=prefix; cmd $var=~.
=
cmd prefix=~
cmd --prefix=~
--prefix
cmd "p"refix=~
p
var=prefix; cmd $var=~
In zsh, you can set the magic_equal_subst option for ~ to be expanded after any unquoted =.
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
In the case of ~ (as opposed to ~user), you can just use $HOME instead:
~user
$HOME
cmd --whatever="$HOME/whatever"
~ expands to the value of $HOME. If $HOME is not set, behaviour varies between shells. Some shells query the user database. If you want to take that into account, you could do (and that's also what you would have to do for ~user):
dir=~ # or dir=~user cmd --whatever="$dir/whatever"
In any case, in shells other than zsh remember you need to quote variable expansions!
36 hours ago
~ has particular expansion rules, which your command doesn't satisfy. Specifically, it is expanded only when unquoted, either at the beginning of a word (e.g. python ~/script.py) or at the beginning of a variable assignment (e.g. PYTHONPATH=~/scripts python script.py). What you have is --data_path=~/blabla which is a single word in shell terms, so expansion is not performed.
python ~/script.py
PYTHONPATH=~/scripts python script.py
--data_path=~/blabla
An immediate fix is to use $HOME shell variable, which follows regular variable expansion rules:
python ptb_word_lm.py --data_path=$HOME/blabla