파일 경로를 지정할 때 '/ home / username /'대신 '~'를 사용할 수없는 이유


43

예를 들어 파일 압축을 풀 때 파일 경로를 가리키는 ~대신 사용할 수 있습니다 ./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/입니까?

자세히 말씀해 주시겠습니까?




@OskarSkog ~인수가 파이썬에 전달되기 전에 쉘이 확장되지 않아야합니까 ? 쉘이 경로에서 백 슬래시 이스케이프를 확장하거나 경로가 인용 된 경우 따옴표를 제거하는 것처럼.
Micheal Johnson

1
와 달리 $VARIABLES,는 ~문자열의 시작 부분에서만 확장됩니다.
Alexis

@OskarSkog는 문제가 파이썬 (확장을 수행하는 이러한 기능하는 것이 무리한 기대를 설정, 기능의 일부를 부족에 고유 한 것을 의미한다 "파이썬은 무엇 ~ 수단 모른다" 이후execD ')가 있어야 UNIX 도구에서 널리 사용할 수는 .
Charles Duffy

답변:


45

~일반적으로 쉘에 의해 확장 된다는 것을 이해해야합니다 . 당신이 호출하는 프로그램은 그것을 보지 못하며, bash가 삽입 한 전체 경로 이름을 봅니다. 그러나 이것은 물결표가 인수의 시작 부분에 있고 인용되지 않은 경우에만 발생합니다.

실행중인 Python 프로그램이 getopt명령 행을 구문 분석하는 것과 같은 모듈을 사용하는 경우 --data-path옵션 의 인수를 별도의 "단어"로 제공하여 물결표 확장을 허용 할 수 있습니다.

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

자체 코드에서는 인수 처리를 사용 getopt하거나 argparse인수로 사용할 수 있으며 @JacobVlijm의 답변이 제안한대로 물결표를 수동으로 확장 할 수도 있습니다.

추신. 물결표는 다음 과 같은 변수 할당 표현식 의 시작 부분에서 확장됩니다 DIRNAME=~/anaconda2. 귀하의 질문에 물결표가 등호를 따르지만,이 사용법은 쉘에 특별한 의미가 없으며 (프로그램에 전달 된 것입니다) 확장을 트리거하지 않습니다.


6
당신이하지 않는 알고 getopt 이미 사용 argparse파이썬을 작성하는 경우.
Nick T

argparse주요 대안이므로 답변에 추가 했지만 개인적으로는 사용하기가 getopt쉽지 않습니다. YMMV.
Alexis

33

파이썬에서 틸드 확장

대답은 짧고 간단합니다.

~다음을 사용 하지 않으면 파이썬이 확장 되지 않습니다 .

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

여기를 참조 하십시오 :

os.path.expanduser (path)
Unix 및 Windows에서 초기 구성 요소가 ~ 또는 ~ user 인 사용자의 홈 디렉토리로 대체 된 인수를 리턴하십시오.

Unix에서는 초기 ~가 설정되면 환경 변수 HOME으로 대체됩니다. 그렇지 않으면 현재 사용자의 홈 디렉토리가 내장 모듈 pwd를 통해 비밀번호 디렉토리에서 검색됩니다. 초기 ~ 사용자는 비밀번호 디렉토리에서 직접 조회됩니다.


11
일반적으로 틸드 확장이 OS 레벨에서 수행된다고 가정해서는 안되며, 유닉스 쉘 (그리고 모두는 아닙니다!)이 당신을 위해하는 일입니다.
farsil

1
더 관련있는 문제는 alexis의 답변에 요약되어 있다고 생각합니다 ~. 쉘 인수 목록 의 위치 .
David Foerster

@ farsil, 나는 동의하지 않습니다. 프로그램을 이식 가능하게 만들 수 있지만 명령 줄에서 실행할 때 특정 시스템에서 수행 할 수 있습니다. 그리고 이것이 askubuntu.com이라는 것을 잊지 말고 우분투는 항상 유닉스입니다 ( 우리가 아는 한 :-)
Alexis

1
@alexis : Ubuntu는 OS 수준에서 물결표 확장을 수행하지 않습니다. 여전히 쉘 기능입니다.
user2357112

1
머리카락을 나누는 중입니다. 아무도 커널이 그렇게하고 있다고 말하지 않았습니다. 요점은 인수를 취하는 프로그램이 수행하지 않는다는 것입니다.
Alexis

12

틸드 확장은 쉘마다 약간 씩 다른 몇 가지 컨텍스트에서만 수행됩니다 .

그것이 수행되는 동안 :

var=~

또는

export var=~

일부 껍질에서. 에 없습니다

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

POSIX 쉘에서.

그것은에 bash생각하지 않을 때 POSIX 준수 모드에서 (로 전화했을 때 같은 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=~

그러나 그의 경우에만하여이 왼쪽에 무엇 =이 확대 될 동안 이렇게, 인용 부호가없는 유효한 변수 이름 모양입니다 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설정되지 않은 행동은 껍질 사이에 다릅니다. 일부 쉘은 사용자 데이터베이스를 조회합니다. 그것을 고려하고 싶다면 할 수 있습니다 (그리고 그것이해야 할 일이기도합니다 ~user).

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

어쨌든, 쉘 이외의 쉘에서는 zsh변수 확장을 인용해야합니다!


1
Bash의 참조 매뉴얼 은 물결표가 변수 할당과 단어의 시작에서만 확장되므로 확장 echo a=~하면 매뉴얼과 모순되는 것으로 보입니다.
ilkkachu

@ ilkkachu, 예 매뉴얼이 불완전합니다. 또한 어떤 문맥 ~이 확장 될 것인지 ( "단어"의 의미) 명확하게 지정하지 않습니다 . 자세한 내용은 답변 상단의 링크를 참조하십시오.
Stéphane Chazelas

6

~명령이 충족하지 않는 특정 확장 규칙이 있습니다. 특히, 단어의 시작 (예 :) python ~/script.py또는 변수 할당의 시작 (예 :)에서 인용 부호가없는 경우에만 확장됩니다 PYTHONPATH=~/scripts python script.py. 당신이 가진 것은 --data_path=~/blabla쉘 용어에서 하나의 단어이므로 확장이 수행되지 않습니다.

즉각적인 수정은 $HOME일반적인 변수 확장 규칙을 따르는 쉘 변수 를 사용 하는 것입니다.

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

약간 단순화 된 것인데, 와 같이 물결 확장이 수행 된 다른 컨텍스트가PATH=$PATH:~/bin 있습니다. 또한 $HOME인용 이 필요하거나 split + glob이 아닌 쉘에 적용됩니다 zsh.
Stéphane Chazelas

@sch 죄송하지만 의견에 제공 한 링크는 물결표 확장에 대한 언급없이 광 마우스에 대한 질문으로 이어집니다. 설명해 주시겠습니까?
Sergiy Kolodyazhnyy

좋은 대답입니다. 이 섹션에서는 기본적으로 bash수동 상태를 요약 Tilde Expansion합니다. +1
Sergiy Kolodyazhnyy

죄송합니다, 나는 [link](/a/146697)우리가 여기에 다른 사이트에 있다는 것을 몰랐기 때문에 유닉스 .SE에서 사이트 내 링크를 사용하는 데 익숙 합니다. 링크는에해야
스테판 Chazelas가
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.