본문 바로가기
C.W.K.
Stream
Lesson 03 of 05 · published

패키지는 통째로, 심링크는 링크로

~12 min · packages, symlinks, traversal

Level 0Finder 에서 헤매는 중
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"복사가 몇 번이고 다시 던지는 질문. 이 안으로 들어가야 하나, 하나로 봐야 하나. 잘못 고르면 앱을 망가뜨리거나 테라바이트를 복제해."

폴더처럼 보이지만 폴더가 아닌 것

.app, .rtfd, 여러 문서 형식. 이것들은 패키지야. 디스크에선 폴더인데 시스템과 사용자한테는 하나로 취급되는 물건이지. Waygate 가 이걸 안으로 들어가 파일 하나씩 복사한다면, 중간에 끊겼을 때 겉보기엔 설치된 것 같지만 실은 망가진 .app 이 남을 수 있어. 그래서 기본은 이래. 패키지는 하나야. 안으로 안 들어가고 통째로 복사해. 'Show Package Contents' 로 안을 들여다볼 수는 있지만, 그건 보는 방식이 달라지는 거지 복사 방식이 달라지는 게 아니야.

심링크는 표시니까 표시로 복사해

심링크는 다른 경로를 가리키는 작은 파일이야. 링크로 복사하면 뜻이 살아. 사본도 원본이 가리키던 곳을 가리키니까. 대신 무턱대고 따라가면 두 가지 사고가 기다려. 링크가 가리키던 몇 기가짜리 대상을 통째로 복제하거나, 뱅뱅 도는 고리에 빠져 끝없이 파고들거나. 그래서 기본은 조심하는 쪽이야. 심링크는 링크로 복사하고 대상까지 따라가지 않아.

둘 아래 깔린 규칙 하나

패키지와 심링크는 같은 원칙의 두 얼굴이야. 안으로 들어가는 순간 작업의 뜻이 달라지니까, 들어갈지 말지는 분명히 정해야 한다. 패키지 안으로 들어가면 '이 앱을 복사' 가 '이 백 개 파일을 복사' 로 바뀌어. 심링크를 따라가면 '이 표시를 복사' 가 '그게 가리키는 뭐든 복사' 가 되고. Waygate 의 기본은 늘 조심하는 쪽이야. 보이는 그대로 하나로 다루고, 더 깊이 들어가는 건 안 물어보고 지나간 재귀 함수의 사고가 아니라 분명히 고른 결정이어야 해.

패키지는 기본적으로 하나로 다루고, 심링크는 따라가지 않고 링크로 복사해. 안으로 들어가면 작업의 뜻이 달라지니까 그건 늘 분명한 선택이어야 해. 뭘 보고 있는지 확인도 안 한 재귀 함수가 흘러가는 대로 결정할 일이 아니야.
심링크 고리와 뜻밖의 테라바이트. 파일 도구의 고전적인 사고 두 가지. 자기 위쪽을 가리키는 심링크가 있으면 무턱대고 따라가는 복사가 영원히 돌고, 커다란 외장 볼륨을 가리키는 심링크가 있으면 '이 폴더 복사' 가 테라바이트를 조용히 퍼 나르지. 둘 다 링크를 기본으로 따라가서 생겨. 링크를 링크로 복사하면 둘 다 애초에 불가능해져.

Code

들어가기 전에 뭔지부터 가려내기·swift
func copyGraph(for url: URL) throws -> CopyNode {
    let vals = try url.resourceValues(forKeys: [.isSymbolicLinkKey, .isPackageKey,
                                                .isDirectoryKey])
    if vals.isSymbolicLink == true {
        return .link(url)                 // copy the POINTER, don't follow it
    }
    if vals.isPackage == true {
        return .atomicItem(url)           // copy WHOLE, don't descend
    }
    if vals.isDirectory == true {
        return .directory(url)            // real folder: traverse (bounded, lazy)
    }
    return .file(url)
}
// The default at every node is the CONSERVATIVE reading. Descending into a
// package or following a link is a separate, explicit code path -- never the
// fall-through behavior of a recursive walk that didn't classify first.

External links

Exercise

자기 자신이 든 폴더를 도로 가리키는 심링크를 하나 만들어봐. 그리고 링크를 따라가며 복사하는 도구를 상상하고 뭐가 벌어지는지 따라가봐. 이번엔 어디로 복사할 폴더 안에 홈 폴더 전체를 가리키는 심링크를 넣어봐. 따라가는 복사는 뭘 할까? 왜 '링크를 링크로 복사' 하면 두 경우 다 심심한 일이 되는지 설명해봐.
Hint
자기를 가리키는 심링크는 따라가는 복사를 끝없이 돌게 만들어. 이름이나 디스크가 바닥날 때까지. 홈 폴더 심링크는 '작은 폴더 하나 복사' 를 홈 전체 복사로 부풀리고. 링크를 링크로 복사하면 심링크는 작은 표시 파일 하나로 저장돼. 파고들 것도, 부풀 것도 없지. 풀어보지 않았으니 두 사고 다 아무 일도 아니게 돼.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.