symlink
에 os.stat()
을 호출하면 파이썬은 OSError
예외를 발생시킵니다. 이것은 그것을 찾는 데 유용합니다. 그러나 os.stat()
에서 비슷한 예외가 발생할 수있는 몇 가지 이유가 있습니다. 리눅스에서 파이썬으로 깨진 symlinks
을 탐지하는 더 정확한 방법이 있습니까?파이썬과의 잘못된 심볼릭 링크 찾기
답변
일반적인 파이썬 속담이보다 용서를 물어 쉽게이다 허가. 실생활에서 나는이 진술의 팬이 아니지만, 많은 경우에 적용됩니다. 일반적으로 코드에서 두 번의 호출 사이에 파일에 어떤 일이 생길지 모르기 때문에 같은 파일에서 두 개의 시스템 호출을 연결하는 코드를 피하려고합니다. 뭔가 다른 사용자의 경우 테스트 후를 삭제 한 경우, 실패 예외를 발생하고, 나머지를 중지 할 수 있습니다
if os.path.exists(path):
os.unlink(path)
두 번째 호출 (os.unlink) :
일반적인 실수는 같은 것을 작성하는 것입니다 함수가 실행되는 것을 막을 수 있습니다.(실제 상황에서는 이것이 발생하지 않는다고 생각할 수도 있지만 지난 주 코드베이스에서 다른 버그를 방금 습득했습니다. 몇몇 프로그래머가 머리를 긁고 'Heisenbug'라고 주장하는 버그가있었습니다. 지난 몇 개월)
그래서, 특정 경우에, 나는 아마 할 것 :
try:
os.stat(path)
except OSError, e:
if e.errno == errno.ENOENT:
print 'path %s does not exist or is a broken symlink' % path
else:
raise e
는 여기 성가심 그 합계 단지가 아닌 심볼릭 링크와 깨진 동일한 오류 코드를 반환이다 symlink.
그래서, 난 당신이 자성을 중단하는 것보다 선택의 여지가 추측하고
if not os.path.exists(os.readlink(path)):
print 'path %s is a broken symlink' % path
파이썬없이 하드 링크 테스트를 언급 할 수 있습니까?/bin/test에는 파일이 inode를 공유 할 때 true 인 FILE1 -ef FILE2 조건이 있습니다.
따라서 find . -type f -exec test \{} -ef /path/to/file \; -print
과 같은 것은 특정 파일에 대한 하드 링크 테스트에 사용할 수 있습니다. man test
을 읽는 날을 제공하고, 해당 파일이 심볼릭 링크 인 경우 하나 개의 파일에 모두 작업과 대상이없는 경우를 알려하지 않는 그러나, true를 반환하는 -L
및 -h
의 언급
. 일반 파일에 대한 심볼릭 링크의 경우는 타겟팅 할 수 있는지 여부에 대한 테스트로 작동
내가 파일을 열 수있는 경우 head -0 FILE1
이 0
의 종료 코드를 반환 찾을 않았다 및 1
이 할 수없는 경우, 읽을 수 있습니다.
저는 파이썬 녀석이 아니지만 os.readlink()처럼 보입니까? 내가 펄에서 사용할 논리는 readlink()를 사용하여 타겟을 찾고 stat()를 사용하여 타겟이 존재하는지 테스트하는 것이다.
편집 : 필자는 readlink 데모 링크가있는 일부 펄을 썼습니다. 나는 펄의 합계와 readlink를하고 파이썬의 os.stat()와 os.readlink는() 시스템 호출에 대한 두 래퍼 생각, 그래서 이것은 잘 개념 증명 코드로 합리적인 해석한다 :
wembley 0 /home/jj33/swap > cat p
my $f = shift;
while (my $l = readlink($f)) {
print "$f -> $l\n";
$f = $l;
}
if (!-e $f) {
print "$f doesn't exist\n";
}
wembley 0 /home/jj33/swap > ls -l | grep ^l
lrwxrwxrwx 1 jj33 users 17 Aug 21 14:30 link -> non-existant-file
lrwxrwxrwx 1 root users 31 Oct 10 2007 mm -> ../systems/mm/20071009-rewrite//
lrwxrwxrwx 1 jj33 users 2 Aug 21 14:34 mmm -> mm/
wembley 0 /home/jj33/swap > perl p mm
mm -> ../systems/mm/20071009-rewrite/
wembley 0 /home/jj33/swap > perl p mmm
mmm -> mm
mm -> ../systems/mm/20071009-rewrite/
wembley 0 /home/jj33/swap > perl p link
link -> non-existant-file
non-existant-file doesn't exist
wembley 0 /home/jj33/swap >
os.lstat()하는 것이 도움이 될 수 있습니다 . lstat()가 성공하고 stat()가 실패하면 아마 깨진 링크 일 것입니다.
당신은에 심볼릭 링크 점은, 다음 사용 유효한 파일인지를 결정하려고 것을 얻을 realpath()를 사용하여 시도 할 수는 파일입니다.
는 (나는 순간에 그것을 시도 할 수없는, 그래서 당신은 그것을 함께 놀러 당신이 무엇을 얻을 참조 할 것)이 원자 아니라 작동 그런 짓을. 경로는 기존 경로를 참조하는 경우 (환상적인 설명서를 읽고) RTFM 에 의해 실제로
os.path.islink(filename) and not os.path.exists(filename)
우리는
반환 진정한
os.path.exists (경로)를 참조하십시오. 깨진 심볼릭 링크에 대해 False를 반환합니다.
또한 말한다 : 권한이 경로가 물리적으로 존재하는 경우에도, 요청 된 파일에() os.stat을 실행하기 위해 부여되지 않은 경우 일부 플랫폼에서
는,이 함수는 False를 반환 할 수 있습니다.
권한이 걱정되면 다른 조항을 추가해야합니다.
임을 가리킨다. – esmit
비슷한 문제가 있습니다. 예를 들어 부모 디렉토리에서 부러진 심볼 링크를 발견하는 경우에도 마찬가지입니다. 또한 많은 수의 파일을 처리하는 응용 프로그램에서 모든 파일을 기록하려고했지만 너무 많이 반복하지 않았습니다.
여기는 단위 테스트를 포함하여 내가 생각해 낸 것입니다.
fileutil.py :
import os
from functools import lru_cache
import logging
logger = logging.getLogger(__name__)
@lru_cache(maxsize=2000)
def check_broken_link(filename):
"""
Check for broken symlinks, either at the file level, or in the
hierarchy of parent dirs.
If it finds a broken link, an ERROR message is logged.
The function is cached, so that the same error messages are not repeated.
Args:
filename: file to check
Returns:
True if the file (or one of its parents) is a broken symlink.
False otherwise (i.e. either it exists or not, but no element
on its path is a broken link).
"""
if os.path.isfile(filename) or os.path.isdir(filename):
return False
if os.path.islink(filename):
# there is a symlink, but it is dead (pointing nowhere)
link = os.readlink(filename)
logger.error('broken symlink: {} -> {}'.format(filename, link))
return True
# ok, we have either:
# 1. a filename that simply doesn't exist (but the containing dir
does exist), or
# 2. a broken link in some parent dir
parent = os.path.dirname(filename)
if parent == filename:
# reached root
return False
return check_broken_link(parent)
단위 테스트 : 심볼릭 링크는 디렉토리로서 파일 missuses 경우
import logging
import shutil
import tempfile
import os
import unittest
from ..util import fileutil
class TestFile(unittest.TestCase):
def _mkdir(self, path, create=True):
d = os.path.join(self.test_dir, path)
if create:
os.makedirs(d, exist_ok=True)
return d
def _mkfile(self, path, create=True):
f = os.path.join(self.test_dir, path)
if create:
d = os.path.dirname(f)
os.makedirs(d, exist_ok=True)
with open(f, mode='w') as fp:
fp.write('hello')
return f
def _mklink(self, target, path):
f = os.path.join(self.test_dir, path)
d = os.path.dirname(f)
os.makedirs(d, exist_ok=True)
os.symlink(target, f)
return f
def setUp(self):
# reset the lru_cache of check_broken_link
fileutil.check_broken_link.cache_clear()
# create a temporary directory for our tests
self.test_dir = tempfile.mkdtemp()
# create a small tree of dirs, files, and symlinks
self._mkfile('a/b/c/foo.txt')
self._mklink('b', 'a/x')
self._mklink('b/c/foo.txt', 'a/f')
self._mklink('../..', 'a/b/c/y')
self._mklink('not_exist.txt', 'a/b/c/bad_link.txt')
bad_path = self._mkfile('a/XXX/c/foo.txt', create=False)
self._mklink(bad_path, 'a/b/c/bad_path.txt')
self._mklink('not_a_dir', 'a/bad_dir')
def tearDown(self):
# Remove the directory after the test
shutil.rmtree(self.test_dir)
def catch_check_broken_link(self, expected_errors, expected_result, path):
filename = self._mkfile(path, create=False)
with self.assertLogs(level='ERROR') as cm:
result = fileutil.check_broken_link(filename)
logging.critical('nothing') # trick: emit one extra message, so the with assertLogs block doesn't fail
error_logs = [r for r in cm.records if r.levelname is 'ERROR']
actual_errors = len(error_logs)
self.assertEqual(expected_result, result, msg=path)
self.assertEqual(expected_errors, actual_errors, msg=path)
def test_check_broken_link_exists(self):
self.catch_check_broken_link(0, False, 'a/b/c/foo.txt')
self.catch_check_broken_link(0, False, 'a/x/c/foo.txt')
self.catch_check_broken_link(0, False, 'a/f')
self.catch_check_broken_link(0, False, 'a/b/c/y/b/c/y/b/c/foo.txt')
def test_check_broken_link_notfound(self):
self.catch_check_broken_link(0, False, 'a/b/c/not_found.txt')
def test_check_broken_link_badlink(self):
self.catch_check_broken_link(1, True, 'a/b/c/bad_link.txt')
self.catch_check_broken_link(0, True, 'a/b/c/bad_link.txt')
def test_check_broken_link_badpath(self):
self.catch_check_broken_link(1, True, 'a/b/c/bad_path.txt')
self.catch_check_broken_link(0, True, 'a/b/c/bad_path.txt')
def test_check_broken_link_badparent(self):
self.catch_check_broken_link(1, True, 'a/bad_dir/c/foo.txt')
self.catch_check_broken_link(0, True, 'a/bad_dir/c/foo.txt')
# bad link, but shouldn't log a new error:
self.catch_check_broken_link(0, True, 'a/bad_dir/c')
# bad link, but shouldn't log a new error:
self.catch_check_broken_link(0, True, 'a/bad_dir')
if __name__ == '__main__':
unittest.main()
- 1. Windows에서 잘못된 심볼릭 링크 찾기 및 삭제
- 2. android : 심볼릭 링크 결정
- 3. Windows의 심볼릭 링크
- 4. 파이썬에서 심볼릭 링크 복사하기
- 5. 심볼릭 링크 된 Rsync
- 6. Windows의 심볼릭 링크?
- 7. Kohana의보기에 대한 심볼릭 링크
- 8. 심볼릭 링크 문제
- 9. 카피스트라의 심볼릭 링크 문제?
- 10. 심포니 심볼릭 링크 문제
- 11. 서버에 심볼릭 링크 업로드하기
- 12. Windows에서의 심미안 심볼릭 링크
- 13. 심볼릭 링크 확인
- 14. 심볼릭 링크 한도 - Windows
- 15. TortoiseSVN을 심볼릭 링크
- 16. 네트워크를 통한 심볼릭 링크 복사
- 17. 심볼릭 링크 - 대소 문자 민감도
- 18. 비트 버킷에 대한 심볼릭 링크
- 19. 심볼릭 링크 나열에 도움이 필요합니다.
- 20. 서브 폴더가있는 Tomcat 심볼릭 링크
- 21. rpmbuild를 통한 심볼릭 링크 패키징?
- 22. perl 심볼릭 링크 된 경로
- 23. TYPO3 확장 및 심볼릭 링크
- 24. 프로그램에 대한 심볼릭 링크 생성
- 25. CarbonEmacs, 심볼릭 링크 및 dired-find-file
- 26. 내가 심볼릭 링크를 생성 한 심볼릭 링크 레드햇을 리눅스
- 27. 특정 이름과 심볼릭 링크가없는 폴더 찾기
- 28. 가상 파일 시스템에서 심볼릭 링크 구현
- 29. NTFS 접합점과 심볼릭 링크 (디렉토리 용)
- 30. 자바 코드 컴파일을위한 라이브러리에 대한 심볼릭 링크
readlink를도 == ENOTDIR errno를 설정할 수있다. –
os.readlink (path)는 'path'링크에 target에 대한 상대 경로가 주어지면 실제 경로를 얻지 못할 수도 있습니다. 예를 들어 path가 '../target'에 링크되어있는 경우 링크가없는 경로에서 스크립트를 실행하면 os.path.exists (os.readlink (path))는 경로에서 false를 반환합니다. 스크립트의 상위 디렉토리에는 'target'이라는 파일이나 폴더가 없습니다. 이것을 피하는 안전한 방법은 os.path.exists (os.path.realpath (path))를 사용하는 것입니다. – AplusG
이렇게해도 충분하지 않습니다. realpath는 현재 실행중인 스크립트의 현재 실행 디렉토리와 관련하여 symlink의 경로를 해석하지만 심볼 링크는 심볼 링크가있는 폴더에 상대적으로 운영 체제에 의해 해석됩니다. 당신이해야 할 일은 다음과 같이하십시오. link_target = os.readlink (경로) dir = os.path.dirname (경로) os.path가 아닌 경우.isabs (link_target) : link_target = os.path.join (DIR, link_target) 경우 os.path.exists (link_target) : #은 당신이이 나쁜 심볼릭 링크 –