셸 스크립트에서 심볼릭 링크 해결하는 방법
유닉스 계열 시스템에서 심볼릭 링크(또는 symlink)를 다루는 것은 경우에 따라 까다로울 수 있습니다. 특히 symlink가 가리키는 실제 경로를 찾고자 할 때 더욱 그렇습니다. 셸 스크립트를 작성하고 중간 심볼릭 링크를 해결한 후 대상의 전체 경로를 결정해야 한다면, 여기서 해결책을 찾을 수 있습니다. 이 블로그 게시물에서는 이를 효율적으로 달성하는 방법을 설명할 것입니다.
문제 이해하기
심볼릭 링크 foo
가 다른 디렉토리 bar
를 가리키는 상황을 상상해 보세요. cd foo
와 pwd
같은 명령어를 실행할 때, 셸은 하위 구조를 명확히 드러내지 않아 대상의 전체 경로를 유추하기 어렵게 만듭니다.
예를 들어:
ls -ld foo bar
drwxr-xr-x 2 greg greg 68 Aug 11 22:36 bar
lrwxr-xr-x 1 greg greg 3 Aug 11 22:36 foo -> bar
다음과 같이 실행하면:
cd foo
pwd
출력은 단순히 /Users/greg/tmp/foo
일 것입니다. 이는 foo
가 가리키는 실제 경로인 /Users/greg/tmp/bar
를 찾고자 할 때 별로 도움이 되지 않습니다.
해결책
다행히도, C 프로그래밍에 깊이 들어가지 않고도 셸 스크립트에서 symlink를 해결할 수 있는 내장 명령어들이 있습니다. 다음은 이를 수행하는 방법입니다:
pwd
명령어 사용하기
명령어 pwd -P
는 현재 작업 디렉토리를 인쇄하는 데 사용되며, 모든 symlink를 해결하여 대상의 절대 경로를 제공합니다. pwd -P
를 실행하면:
pwd -P
모든 symlink를 해결한 후 전체 경로를 반환합니다.
getcwd
사용하기
또 다른 방법은 C의 unistd.h
라이브러리에서 getcwd
함수를 활용하는 것입니다. 하지만 스크립팅을 할 경우, 단순히 셸 명령어를 사용할 수 있습니다. getcwd
는 pwd -P
와 유사한 동작을 한다는 것을 아는 것이 좋습니다.
해결 함수 만들기
이 명령어들을 함수로 감싸면 작업이 더 수월해집니다. 다음은 Bash 셸에서 간단한 resolve
함수의 예입니다:
resolve() {
# 제공된 경로를 사용하여 해결합니다
local target=$1
# `readlink -f`는 symlink를 따라가며 전체 경로를 반환합니다
local full_path=$(readlink -f "$target")
echo "$full_path"
}
예제 사용법
이제 함수를 다음과 같이 호출하면:
resolve "foo"
출력은 다음과 같습니다:
/Users/greg/tmp/bar
이 패턴은 셸 스크립트 환경에서 만난 모든 symlink의 전체 경로를 접근할 수 있게 해줍니다.
보너스: 사용자 홈 경로 해결하기
티르드 표기법(예: ~username
)을 사용하여 홈 디렉토리를 해결하려면, Bash는 자동으로 이러한 경로를 확장합니다. 따라서 이를 resolve
함수와 원활하게 결합할 수 있습니다.
결론
셸 스크립트에서 심볼릭 링크를 해결하는 것은 복잡할 필요가 없습니다. pwd -P
명령어를 사용하거나 readlink
를 사용하는 resolve
와 같은 도우미 함수를 생성함으로써, 대상의 전체 경로를 효과적으로 결정할 수 있습니다. 이 기술은 유닉스 계열 환경에서 작업하는 누구에게나 필수적이며 스크립트를 훨씬 더 강력하고 유용하게 만드는 데 도움을 줍니다.
심볼릭 링크를 잘 관리하면 디렉토리 구조를 탐색하거나 복잡한 셸 스크립트를 작성하는 동안 시간과 혼란을 절약할 수 있습니다.