심볼릭 링크에서 일반 파일 구별


22

일반 파일을 심볼릭 링크와 구별 해야하는 bash 스크립트를 작성 중입니다. if / test 표현식 으로이 작업을 수행 할 수 있다고 생각했지만 예상대로 작동하지 않습니다.

$ touch regular_file
$ test -f regular_file; echo $?
0
$ test -h regular_file; echo $?
1
$ ln -s regular_file symlink
$ test -h symlink; echo $?
0
$ test -f symlink; echo $?
0

왜 그런가요? 그리고 어떻게 제대로 할 수 있습니까?

답변:


20

테스트를 약간 혼란스럽게하는 것처럼 보입니다. 두 가지 테스트를 모두 실행할 필요는 없습니다.이 경우에 필요한 유일한 -h것은 파일이 심볼릭 링크인지를 알려주는 것입니다.

test -h file && echo "is symlink" || echo "is regular file"

-f객체가 파일 인 경우 테스트는 당신을 알려줍니다. 이 반환 0은 디렉토리 또는 디바이스 노드 또는 디렉토리에 대한 심볼릭 링크가 있다면,하지만 돌아갑니다 1파일로 심볼릭 링크에.

디렉토리가 아닌 파일에 대한 심볼릭 링크인지 알아야하는 경우 두 테스트 결과를 약간의 논리와 결합해야합니다.


I는 문서로부터 알 수있는 바와 같이, 차이 -e-f즉 하였다 -e(모든 종류의) 파일이 존재하는 경우에 알을 사용하고, -f파일이 존재하고 정규 파일 인 경우 시험 구체적이었다. "정규 파일"이 무엇인지 오해 한 것 같습니다.
Nupraptor

1
@Nupraptor : 네, 당신은 문서를 오해했습니다. 심볼릭 링크는 파일이 될 수있는 다른 유형의 노드 (블록 장치 노드, 문자 장치 노드, 디렉토리 등)와 달리 일반 파일로 간주됩니다. 파일 형식을 알고 싶다면 -h심볼릭 링크, -p명명 된 파이프 등 파일 형식 별 테스트를 실행해야합니다 .
Caleb

그렇다면 파일이 파이프 나 심볼릭 링크가 아닌 일반 파일인지 어떻게 테스트합니까? 이것에 대해 다른 질문을 열어야합니까?
Nupraptor

@Nupraptor : 유일한 이상한 경우는 일반 파일로 연결되는 심볼릭 링크입니다. 그렇지 않으면 일반 파일로 테스트하면 일반 파일입니다.
David Schwartz

3
test -f 디렉토리는 0이 아닌 1을 리턴합니다 : test -f. ; 에코 $? (출력 1)
다항식

7

@Caleb은 스크립트를 심볼릭 링크로 테스트하는 것에 대해 정확합니다. 그러나 왜 빠졌는지에 대한 부분은 궁금했습니다. coreutils 소스 코드를보고 테스트 결과를 추적하면 심볼릭 링크 테스트를 실행할 때 lstat를 사용하고 -f 테스트를 사용하는 경우 실제로 symlink 다음에 'stat'를 호출한다는 것을 알 수 있습니다.

$ ln -s varnish_config XXX
$ strace -s 2000 test -L XXX 2>&1 | grep XXX
execve("/usr/bin/test", ["test", "-L", "XXX"], [/* 47 vars */]) = 0
lstat("XXX", {st_mode=S_IFLNK|0777, st_size=14, ...}) = 0

$ strace -s 2000 test -L varnish_config 2>&1 | grep varnish
execve("/usr/bin/test", ["test", "-L", "varnish_config"], [/* 47 vars */]) = 0
lstat("varnish_config", {st_mode=S_IFREG|0664, st_size=1046, ...}) = 0

$ strace -s 2000 test -f XXX 2>&1 | grep XXX
execve("/usr/bin/test", ["test", "-f", "XXX"], [/* 47 vars */]) = 0
stat("XXX", {st_mode=S_IFREG|0664, st_size=1046, ...}) = 0

통계 매뉴얼 페이지에서 :

   stat() stats the file pointed to by path and fills in buf.

   lstat() is identical to stat(), except that if path is a symbolic link,
   then the link itself is stat-ed, not the file that it refers to.

이는 지정된 파일 이름이 일반 파일 또는 일반 파일 자체에 대한 심볼릭 링크 인 경우 -f 테스트가 true를 반환 함을 의미합니다.

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