47 votes

Pourquoi n'ai-je pas pu utiliser ' ~ ' au lieu de ' /home/username/ ' pour indiquer le chemin d'accès au fichier ?

Je peux utiliser ~ au lieu de /home/username/ pour pointer vers un chemin d'accès à un fichier lorsque, par exemple, on décompresse un fichier .zip fichier.

Cependant, aujourd'hui, lorsque j'ai suivi la même méthode pour exécuter un exemple de RNN dans le 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

J'ai ensuite remplacé ~ con /home/username/ et cela a fonctionné correctement.

Pourquoi ne pourrais-je pas utiliser ~ au lieu de /home/username/ pour indiquer le chemin d'accès au fichier lors de l'exécution d'un exemple RNN ?

Pouvez-vous m'en parler en détail ?

50voto

alexis Points 1018

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 tel qu'il est inséré par bash. Mais cela ne se produit que lorsque le tilde se trouve au début d'un argument (et qu'il n'est pas cité).

Si le programme Python que vous exécutez utilise un module tel que getopt pour analyser sa ligne de commande, vous pouvez donner l'argument de la commande --data-path comme un "mot" séparé pour permettre l'expansion du tilde :

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

Dans votre propre code, vous pouvez utiliser getopt o argparse pour le traitement des arguments, et pourrait également étendre manuellement les tildes comme le suggère la réponse de @JacobVlijm.

PS. Le tilde est également étendu au début d'un Shell expression d'affectation de variable comme DIRNAME=~/anaconda2 ; bien que le tilde dans 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.

38voto

Jacob Vlijm Points 78990

Expansion du tilde en Python

La réponse est courte et simple :

Python ne se développe pas ~ à moins que vous n'utilisiez :

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

Voir aussi aquí :

os.path.expanduser(path)
Sous Unix et Windows, l'argument est retourné avec un composant initial ~ ou ~user remplacé par le répertoire personnel de l'utilisateur.

Sous Unix, un ~ initial est remplacé 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 par l'intermédiaire du module intégré pwd. Un ~utilisateur initial est recherché directement dans le répertoire des mots de passe.

13voto

Greg B Points 171

L'expansion du tilde ne se fait que dans quelques contextes qui varient légèrement d'un shell à l'autre .

Alors qu'elle est réalisée en :

var=~

Ou

export var=~

dans certaines coquilles. Il n'y en a pas dans les

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

dans les shells POSIX.

Il est en bash bien que lorsqu'il n'est pas en mode de conformité POSIX (comme lorsqu'il est appelé en tant que sh ou 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=~

Toutefois, ce n'est le cas que lorsque ce qui se trouve à gauche de l'icône = a la forme d'un nom de variable valide sans guillemets, de sorte qu'alors qu'il serait développé en cmd prefix=~ il n'y aurait pas de cmd --prefix=~ (en tant que --prefix n'est pas un nom de variable valide) ni dans cmd "p"refix=~ (à cause de la citation p ) ni en var=prefix; cmd $var=~ .

En zsh , vous pouvez régler la magic_equal_subst option pour les ~ à développer après tout = .

$ 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 au lieu de cela :

cmd --whatever="$HOME/whatever"

~ s'étend à 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 des utilisateurs. Si vous voulez prendre cela en compte, vous pouvez le faire (et c'est aussi ce que vous devriez faire pour ~user ):

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

En tout état de cause, dans les coquilles autres que zsh n'oubliez pas que vous devez citer les expansions variables !

7voto

Dmitry Grigoryev Points 1769

~ a des règles d'expansion particulières, que votre commande ne satisfait pas. En particulier, elle n'est développée que lorsqu'elle n'est pas citée, soit au début d'un mot (par ex. python ~/script.py ) ou au début d'une assignation de variable (par exemple PYTHONPATH=~/scripts python script.py ). Ce que vous avez, c'est --data_path=~/blabla qui est un mot unique en termes de Shell, de sorte que l'expansion n'est pas effectuée.

Une solution immédiate consiste à utiliser $HOME Shell, qui suit les règles d'expansion des variables normales :

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

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X