Linux는 여러 개의 연속 경로 구분 기호 (/ home ///// username /// file)를 어떻게 처리합니까?


111

파일 위치를 scp 하위 프로세스로 전달하는 파이썬 스크립트를 작성 중입니다. 괜찮습니다. 그러나 경로에 이중 '이있는 파일 이름으로 경로를 연결할 수있는 상황에 처해 있습니다 /. bash는 파일 구분 기호가 여러 개인 경우 신경 쓰지 않는다는 것을 알고 있지만 정확히 어떻게 수정되는지 궁금합니다. 여분 /의 s 를 제거하는 bash입니까, 아니면 실제로 중요하지 않습니까?

/연결하는 동안 추가 코드를 확인하기 위해 몇 줄의 코드를 저장하기 때문에 묻습니다 . 큰 문제가 아니라는 것도 알고 있지만 궁금합니다. 나는 선이있는 bash는 스크립트가 cd //usr(대신 cd /usr여러 사용에 의미가있을 수 있습니다 의미하는 것), /경로에들


7
추가 코드 줄에 투자했습니다.
Stefan

5
아무도 신경 쓰지 않는 경우를 대비하여 실제로 파이썬 join과 그 abspath와 같은 명령을 사용했습니다.
Falmarri

답변:


165

여러 개의 슬래시가 허용되며 단일 슬래시와 같습니다. 로부터 단일 유닉스 규격 (버전 3) , 기본 정의 §3.266 경로 : ". 여러 개의 연속 슬래시 한 슬래시와 같은 것으로 간주됩니다"

한 가지 예외가 있습니다. 경로 이름이 정확히 두 개의 슬래시로 시작하면 다르게 취급 될 수 있습니다 (참조 : 기본 정의 §4.11 경로 이름 확인 ). Linux 자체는이 작업을 수행하지 않지만 일부 응용 프로그램과 다른 유닉스 시스템 (예 : Cygwin)도 마찬가지입니다.

/경로명의 끝에 후행 은 경로명이 디렉토리를 참조하도록합니다. ( POSIX 1003.1-2001 (Single Unix v3) 기본 정의 §4.11 경로 이름 확인 에서, 후행 /은 후행 과 동일합니다 /.. POSIX 1003.1-2008 (Single Unix v4) 기본 정의 §4.12/.순서대로 해당 요구 사항을 제거합니다. 존재하지 않는 디렉토리에 대처하기 위해 (예 : mkdir foo/작동해야하지만 mkdir foo/.그렇지 않은 경우- 변경에 대한 이론적 근거 참조 )

디렉토리 항목에 작동하는 프로그램의 경우 디렉토리 foo에 대한 기호 링크 인 경우 전달 foo/은 프로그램이 기호 링크 대신 디렉토리에 작동하도록하는 방법입니다.

¹ 이는 파일 이름에 액세스하는 경우에만 경로 이름 확인에만 적용됩니다. 파일 이름 조작이 다르게 작동 할 수 있습니다. 예를 들어 basenamedirname슬래시를 후행 무시합니다.


7
상응하는 /.이 모호으로 나중에 논의 과정 후에 제거되었습니다. 어쨌든 이러한 종류의 정보를 잘 요약하여 찾는 것은 어렵습니다.
hakre

17

OS는 직접 syscall을 사용하여 C 프로그램을 시도하여 경로에 //로 열면 관심이없는 것처럼 보입니다.

파이썬 라이브러리 함수 os.path.normpath를 사용하여 정규화 할 수 있으므로 여분의 문자열을 스캔해야합니다. 다른 언어들도 비슷한 기능을 가지고 있습니다.

http://docs.python.org/library/os.path.html#os.path.normpath


5
normpath의 소스에서 다음 주석에주의하십시오. 경로를 정규화하십시오 (예 : A // B, A /./ B 및 A / foo /../ B). 모두 A / B가됩니다. 심볼릭 링크가 포함 된 경우 경로의 의미가 변경 될 수 있음을 이해해야합니다!
Bluehorn

8

내가 본 모든 유닉스 시스템에서 단일 것과 동일 /하지만 유닉스 표준

두 개의 연속 슬래시로 시작하는 경로 이름은 구현 정의 방식으로 해석 될 수 있지만 두 개 이상의 선행 슬래시는 단일 슬래시로 취급됩니다.

시스템에 따라 특별하게 처리 될 수 있습니다. (일부 구형 Unix 버전 /은 원격 파일 시스템 액세스를 위해 이중 선행 을 사용했으며 여전히 일부 파일이있을 수 있습니다.)


7
Cygwin (실제 UNIX는 아님)은 //remote/...아마도 Windows와의 일관성을 위해 원격 파일 시스템 액세스로 변환 됩니다 \\remote\....
ephemient

2
Windows POSIX compat API도 //remote/...UNC 경로 \\remote\...형식 과 동일하게 취급한다고 생각하지만 (지금은 Google에서 잘 참조 할 수는 없습니다) .
Stephen P

1
Boost.Filesystem의 이식 가능한 경로 이름 은 Unix / POSIX 사양에 따라 절대 //테스트 false를 수행 할 수 있다는 점에서 특별한 방식으로 처리된다는 것을 기억합니다 .

7

os.path.join파이썬에서 사용 하면 여러 개의 슬래시가 없습니다. 문자열을 연결하여 파일 이름을 직접 만드는 것은 열악한 Python 스타일로 간주됩니다.


동의하지만 파일 이름은 명령 문자열의 일부이며 명령 문자열을 파싱하여 파일 이름에 추가하는 대신 (끝에) 추가하고 싶습니다.
Falmarri

1
@ 팔마 리 : 파일 이름을 명령 문자열에 추가 할 수는 없습니다! 명령 문자열은 셸에서 구문 분석되므로 파일 이름의 특수 문자를 인용해야합니다. 따라서 파일 이름을 구성한 다음 파일 이름을 올바르게 지정하여 명령 문자열에 넣으십시오.
Gilles

이것은 실제로 사용하는 프로젝트입니다. 나는 이것에 대해 강력하지 않다는 것을 정당화 할만 큼 명확하지 않았을 것입니다. 이 파일 경로 문자열을 올바르게 이스케이프 된 파일 경로 등을 제공하는 클래스에서 가져옵니다. 그리고 명령 줄 인수에 추가하겠습니다
Falmarri

1
@Falmarri : 따라서 normpath를 사용하여 제어하지 않는 명령 행 값을 정리 한 다음 join을 사용하여 조합하십시오.
Neil Mayhew

이것은 실제로 내가 = \하고있는 일입니다. 나는 /아주 잘 주어진 특별한 경우를 처리 할 수 ​​없습니다 .
Falmarri

3

다른 점이 없다.

여러 슬래시가 무시됩니다 (효과 없음). 예 :

ls -al //usr///////bin/sed

7
정확히 두 개이고 처음에 있을 있습니다. 두 개의 연속 슬래시로 시작하는 경로 이름은 구현 정의 방식으로 해석 될 수 있습니다 . 실제로 나는 이것이 옳다고 생각하고 그들은 그냥 무시된다
Michael Mrozek

고마워 크리스, 나는 설명을 주셔서 감사합니다! (불행히도 OpenID 로그인이 작동하지 않거나 투표 할 것입니다)

@Rob 등록되지 않았지만 여전히 로그인했습니다 (쿠키에 의해 추적 됨). OpenID를 귀하의 계정에 연결하기 위해 지금 등록 할 수는 있지만 어느 쪽이든 투표 할 수 있어야합니다.
Michael Mrozek

Michael에게 감사하지만 "로그인하거나 투표하려면 등록해야합니다". 이메일 주소와 이름 만 사용하면 모든 권한이 없습니다. OpenID가 시간이 초과되어 다른 계정을 만들고 싶지 않다고 생각합니다. 게으른 것에 대한 내 잘못은 추측하지만 도움을 주셔서 감사합니다.

0

물론 경로를 통과하여 가능한 여러 / (슬래시)가있는 경로를 표준화 할 수 있습니다 tr -s

NORMALIZED=$(echo "$UNHYGIENIC" | tr -s / /)

... 그리고 사용 $NORMALIZED

그러나 필요합니다. 내가 아는 것처럼 UNIX 커널은 동시 경로 구분 기호를 무시하거나 개념적으로 처리해야합니다 ... /./...


"해야한다"-> "하지 않아야한다".
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.