콘텐츠로 건너뛰기
Home » 20100404 :: 심볼릭 링크에 대하여

20100404 :: 심볼릭 링크에 대하여

리눅스를 쓰게 되면서 가장 많이 접하는 단어 중의 하나가 바로 ‘심볼릭 링크’라는 말이죠. 복사하기 귀찮거나 그러면 그냥 심볼릭 링크를 만들면 된다는 이야기는 참 많이 들었던 것 같습니다. 대충 앞뒤 상황을 보아하니 윈도의 ‘바로가기(shortcut)’와 같은 개념인 듯 합니다만… 그렇게 대충 알고 지내다가 오늘은 ‘하드 링크’라는 걸 또 알게 되어…. 아… 링크면 링크지 심볼릭은 뭐고 하드 링크는 또 뭐다냐…

윈도의 바로가기와 차이점

리눅스에서의 링크는 윈도의 ‘바로가기’와 비슷하면서도 또 많이 다릅니다. 정확하게는 ‘데이터 혹은 파일의 실체가 아닌 그 곳에 다다르는 통로’라는 개념으로 이해하면 되는데, 실제적으로는 이게 ‘바로가기’와 다를 바가 없다는 거죠. 차이가 있다면 ‘바로가기’는 결국 윈도의 파일 탐색기가 제공하는 경로 데이터 파일임에 반해, 링크는 리눅스의 파일 시스템 자체가 제공하는 기능이라는 이랄까요? 즉 무슨 말인고 하니 윈도 탐색기에서 어떤 프로그램이나 디렉터리의 바로가기를 바탕화면에 생성했다고 하면, 윈도의 바탕화면 폴더에는 해당 바로가기의 ‘파일’이 생성됩니다. 그리고 이 파일 안에는 어떤 아이콘을 표시해야하고, 가리키고 있는 대상의 경로는 무엇인지 따위의 정보가 기록되는 거죠. 우리는 실제로 이 바로가기 파일을 편집해서 참조하는 위치를 바꿀 수도 있어요. 그런데 리눅스에서 어떤 디렉터리에서 링크를 생성하면, 해당 디렉터리에는 목표지점(target)의 이름만이 생성됩니다. 만약 그 대상이 어떤 텍스트 파일이라 하고 cat somelink 라는 명령을 준다면, 링크의 내용이 아닌 목표 지점인 텍스트 파일의 내용이 그대로 출력된다는 이야기입니다. 한마디로 말해, 리눅스의 링크는 그 실체가 없다고 할까요.해당 링크에 접근하는 것은 원본 파일에 접근하는 것일 뿐, 링크 그 자체를 손볼 수 있는 방법은 없는 것처럼 보입니다.
그리고 또 재밌는 것은 링크를 통해 특정 지점에 접근하더라도, 사용자가 바라보는 경로는 마치 링크가 실제로 존재하는 것처럼 보인다는 것입니다. 아니 방금 전까지만 해도 리눅스의 링크는 실체가 없다고 해 놓고서는 무슨 소리냐고 할 수 있는데 사실은 이런거죠.

결국 파일 시스템 내의 어떤 지점이 여러 곳에서 여러 개의 이름을 갖는 것과 똑같다고 생각하면 됩니다. 너무 추상적이라 예를 들자면, 만약 /some/path/source 라는 디렉터리가 존재해서, /usr/local/links 라는 디렉터리에서 해당 지점으로 링크를 만들었다고 합시다. 링크의 이름은 타이핑하기 귀찮으니 s 로 하구요. 그래서 links 디렉터리에서 s로 이동한다면

/usr/local/links$ cd s
/usr/local/links/s$ ls
{실제로 /some/path/source 에 들어있는 파일 리스트가 쫙 뿌려집니다.}

이렇게 됩니다. 즉 링크는 목표지점을 완전히 직접적으로 연결하는 장치이고, 이를 통해 접근하는 경우 사용자는 원본의 경로로 직접 접근하는 것과 ‘아무런 차이점이 없이’ 특정 경로를 바로 액세스하는 효과를 누릴 수 있게되는 것이죠. 사실 이것은 좀 혼란스럽게 느껴질 수 있지만, 단일 자원의 무분별한 중복(복사본으로 넘쳐나는 불행!)을 방지하고 또한 변경 사항이 생기는 경우 모든 것이 동기화되는 개념이기 때문에 (왜냐면 원본은 하나 밖에 없으니까) 상당히 효율적이고 멋진 기능이라 할 수 있다.

하드 링크와 심볼릭 링크

그럼 이제 하드링크와 심볼릭 링크의 차이점에 대해 살펴보겠습니다. 먼저 보통 ‘링크’라고 이야기하면 일반적으로는 심볼릭 링크를 이야기하는 듯 합니다. 하드 링크는 하드 링크라고 별도로 명시하는 듯 하네요. 심볼릭 링크는 말 그대로 이름으로만 존재하는 링크에요. 만약 어떤 파일에 대해 다른 위치에서 심볼릭 링크를 만들었다고 하면, 해당 심볼릭 링크는 파일의 경로+파일이름과 완전히 동일하게 취급됩니다. 마치 링크가 존재하는 그 디렉토리에 텍스트 파일이 있는 것과 똑같은 효과가 있지요.(실제로도 그렇습니다. 링크는 원본 파일이 가진 파일 이름과 같이 또  다른 ‘이름’이니까요) 이 때 원본 파일을 에디터로 수정한 다음, 링크를 통해 해당 파일의 내용을 들여다보면 당연히 수정된 내용이 반영되어 보입니다. 만약 vi와 같은 에디터를 통해 링크를 수정한다면, 그것은 결국 ‘링크의 이름을 가진 원본 텍스트 파일’을 수정하는 것이므로 나중에 원본을 확인해보면 수정된 내용이 반영되어 있기도 하구요. 우리는 그저 “똑같은 파일이 요기잉네”와 같이 취급하면 됩니다.
여기까지는 어려울 것이 없어요. 그럼 하드 링크는 어떻게 동작할까요? 하드링크의 동작도 마찬가지 입니다. 링크를 만들어서 마치 해당 디렉터리에 파일이 위치하는 것처럼 액세스 할 수 있지요. 원본을 수정하면 링크를 통해 확인한 내용이 즉시 바뀐 것을 볼 수 있는 것도 똑같습니다. 그런데 만약, 원본을 지워버리면 어떻게 될까요? 하드 링크의 경우, 원본을 지우더라도 링크를 통해 확인해보면 해당 파일이 그대로 존재하는 것처럼 보입니다. 어이쿠야. 하드링크는 원본이 삭제되더라도 그 내용이 없어지지 않는다는 것이지요. 중요한 것은 원본이 삭제되기 전까지는 하드링크는 일반적인 링크의 역할만 하게 되지만 원본이 지워지게되면 하드 링크는 복사본의 역할을 수행하게 됩니다. 사실 이러한 동작은 거꾸로 특정 파일이 삭제될 때 실제로 파일 시스템 내에서 소멸되지 않고 어딘가에 숨어있으며, 그 위치는 여전히 하드 링크들에 의해 접근이 가능해진다는 이야기가 됩니다. 이건 대용량의 동영상 파일이나 iso 파일로 실험해 볼 수도 있어요. 수 백 메가바이트짜리 대용량 파일에 대해 링크를 생성하더라도 파일 시스템의 사용량은 거의 변화가 없습니다. 단순히 이름만 더 생겼단 의미겠지요. 그런데 원본을 삭제해도 역시 변화가 없다. 변화가 발생하는 것은 원본을 삭제한 후 하드 링크를 (두 개 이상의 하드링크가 존재했다면 모두 다)삭제하였을 때 그렇게 됩니다.
하드 링크 자체는 원본과 동기화된 파일이라고 생각해도 무방하기 때문에 ls -al를 통해 데이터의 유형을 살폈을 때도 그냥 파일과 다름없습니다만, 심볼릭 링크는 l이라고 당당히 링크의 신분을 밝힙니다.
심볼릭 링크는 원래 위치만을 참조하기 때문에 원본을 삭제하면 해당 링크는 그저 허공을 가리킬 뿐, 해당 파일이나 디렉터리가 없다는 에러 메시지를 뿜어내게 됩니다. 이것이 하드 링크와 심볼릭 링크의 차이점입니다. 아, 이제야 왜 하드링크와 소프트링크가 아닌 하드 링크와 심볼릭 링크의 차이점을 알 수 있겠네요. 그것은 ‘소프트링크’라고 쓰면 ‘소프트드링크’처럼 들리기 때문입니다!

링크 만들기

링크를 만드는 명령은 ln입니다. 이 명령은 다음과 같이 사용됩니다.

  1. ln {타겟의 위치} [링크의 이름]
  2. ln -s {타겟의 위치} [링크의 이름]

1번 방법은 하드 링크를 생성합니다. 링크 이름을 별도로 주지 않으면 원본과 같은 이름의 링크가 생성됩니다. 2번처럼 -s 옵션을 주면 심볼릭 링크가 생성됩니다. 역시 링크 이름을 주지 않으면 원본과 같은 이름으로 링크가 생성됩니다. 하드 링크는 원본의 변화나 삭제시 기존 데이터를 보존하는 역할을 합니다. 그것과 관련되어 조금 복잡한 사연을 가지고 있어서 디렉터리 자체는 하드 링크의 생성이 불가능합니다. 파일만 가능하지요. 하지만 심볼릭 링크는 파일이나 디렉터리 모두에 사용될 수 있습니다.

정리. 그리고 하드링크까지 한번에 삭제하기

이렇게 살펴보고 나니 링크라는 게 대단한 건줄 알았는데 별거 아니었구나 하는 생각이 듭니다. 그런데 여기서 한 가지 의문이 드는데, 만약에 어떤 파일이 하드 링크를 여러 곳에 두고 있다면 그 파일을 지운다 한들 실질적으로는 파일시스템 내에 다른 이름으로 살아남아있을 확률이 크다는 이야기입니다. 결국 특정 파일을 완전히 삭제하고 싶다면 참조하고 있는 모든 링크를 찾아보아야 한다는 이야긴데, 특정한 파일을 참조하는 하드 링크를 찾는 방법을 알아보야겠지요?
특정 파일에 대한 하드 링크를 검색하는 것은 결국 ‘똑같은 파일에 대한 다른 이름’을 찾는 것이므로 find 명령의 -samefile 옵션을 사용하면 됩니다. 예를 들면 다음과 같겠지요.

$ find /home -samefile file_that_has_many_hardlinks.mp3

그리고 이들을 한 번에 지워버리고 싶다면 다음과 같은 명령을 사용합니다.

$ find /home -samefile file_that_has_many_hardlinks.mp3 | xargs rm
(xargs는 표준입력으로 받은 항목들을 나누어 뒤에 이어지는 명령에 인수로 넘기는 역할을 한다고 합니다.)

오늘은 여기까지입니다. 이틀 연속 외박을 할 순 없으니까, 이제 집에 가야겠어요. 요즘 일교차가 유난히 큰 듯 한데, 다들 감기 조심하세요. 여러분 안녕~