web-dev-qa-db-fra.com

Pourquoi ne puis-je pas utiliser '~' au lieu de '/ home / nom d'utilisateur /' lorsque je donne le chemin du fichier

Je peux utiliser ~ au lieu de /home/username/ pour désigner un chemin de fichier lorsque, par exemple, vous décompressez un fichier .Zip.

Cependant, aujourd’hui, lorsque j’ai suivi la même procédure pour exécuter un exemple RNN dans un terminal, tensorflow.python.framework.errors_impl.NotFoundError a été lancé.

$ 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

Ensuite, j'ai remplacé ~ par /home/username/ et tout fonctionnait correctement.

Pourquoi ne puis-je pas utiliser ~ au lieu de /home/username/ pour désigner le chemin du fichier lors de l'exécution d'un exemple RNN?

Pourriez-vous me dire en détail?

42
JNing

Vous devez comprendre que ~ est normalement développé par le shell; les programmes que vous appelez ne le voient jamais, ils voient le chemin complet comme inséré par bash. Mais cela ne se produit que lorsque le tilde est au début d'un argument (et n'est pas cité).

Si le programme Python que vous exécutez utilise un module tel que getoptpour analyser sa ligne de commande, vous pouvez donner l'argument de l'option --data-path sous la forme d'un "Word" distinct pour permettre le développement du tilde:

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

Dans votre propre code, vous pouvez utiliser getoptou argparsepour le traitement des arguments. Vous pouvez également développer manuellement les tildes en suivant la suggestion de @ JacobVlijm.

PS Le tilde est également développé au début d’une expression d’affectation de variable Shell comme DIRNAME=~/anaconda2; bien que le tilde de votre question suive également un signe égal, cet usage n'a pas de signification particulière pour le shell (il s'agit simplement d'un élément transmis à un programme) et ne déclenche pas d'expansion.

45
alexis

Expansion de tilde en python

La réponse est courte et simple:

python ne développe pas ~ sauf si vous utilisez:

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

Voir aussi ici :

os.path.expanduser (path)
Sous Unix et Windows, renvoyez l’argument avec un composant initial de ~ ou ~ utilisateur remplacé par le répertoire de base de cet utilisateur.

Sous Unix, une initiale ~ est remplacée par la variable d’environnement HOME si elle est définie; sinon, le répertoire personnel de l’utilisateur actuel est recherché dans le répertoire des mots de passe via le module intégré pwd. Un ~ utilisateur initial est recherché directement dans le répertoire du mot de passe.

32
Jacob Vlijm

L’expansion de tilde n’est réalisée que dans quelques contextes qui varient légèrement d’un shell à l’autre .

Bien qu'il soit exécuté en:

var=~

Ou

export var=~

dans certains coquillages. Ce n'est pas dans

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

dans des coquilles POSIX.

Il est dans bashmais pas en mode de conformité POSIX (comme lorsqu'il était appelé shou lorsque POSIXLY_CORRECT est dans l'environnement):

$ 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=~

Cependant, ce n’est que lorsque ce qui se trouve à gauche de = a la forme d’un nom de variable valide non entre guillemets. Ainsi, même si elle serait développée dans cmd prefix=~, elle ne serait pas dans cmd --prefix=~ (car --prefix n’est pas un nom de variable valide), ni dans cmd "p"refix=~ (car de cette cité pname__) ni dans var=prefix; cmd $var=~.

Dans zshname__, vous pouvez définir l'option magic_equal_subst pour que ~ soit développé après tout = non entre guillemets.

$ 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

Dans le cas de ~ (par opposition à ~user), vous pouvez simplement utiliser $HOME à la place:

cmd --whatever="$HOME/whatever"

~ se développe à la valeur de $HOME. Si $HOME n'est pas défini, le comportement varie d'un shell à l'autre. Certains shells interrogent la base de données utilisateur. Si vous voulez en tenir compte, vous pouvez faire (et c'est aussi ce que vous devez faire pour ~user):

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

Dans tous les cas, dans les shells autres que zshname__, souvenez-vous qu'il vous faut citer les extensions des variables!

12

~ a des règles d'expansion particulières, auxquelles votre commande ne satisfait pas. Plus précisément, il est développé uniquement lorsqu'il est non mis entre guillemets, soit au début d'un mot (par exemple, python ~/script.py), soit au début d'une affectation de variable (par exemple, PYTHONPATH=~/scripts python script.py). Ce que vous avez est --data_path=~/blabla qui est un seul mot en termes de shell, de sorte que l'expansion n'est pas effectuée.

Une solution immédiate consiste à utiliser la variable shell $HOME, qui suit les règles habituelles de développement des variables:

python ptb_Word_lm.py --data_path=$HOME/blabla
6
Dmitry Grigoryev