리눅스 readlink 명령어 사용법 - 심볼릭 링크 추적과 /proc으로 프로세스 실체 확인
이 명령어를 언제 쓰는가
"지금 도는 게 도대체 어느 파일이냐"를 확인할 때 쓴다. /usr/bin/java가 alternatives를 거쳐 어느 JDK로 가는지, /opt/app/current가 어느 릴리스를 보는지, 방금 배포한 링크가 제대로 갈렸는지를 ls -l보다 정확하게 알려 준다. ls는 사람이 읽는 화살표 표기라 파싱하면 안 되지만, readlink는 대상 경로만 깨끗하게 출력한다.
리눅스에서는 여기에 강력한 용법이 하나 더 있다. /proc 아래의 exe, cwd, fd/N은 전부 심볼릭 링크라, readlink로 실행 중인 프로세스의 실제 바이너리·작업 디렉터리·열린 파일을 확인할 수 있다.
기본 형식
readlink [옵션] 파일...
옵션 없이 쓰면 한 단계만 읽는다. 링크가 아니면 아무것도 출력하지 않고 종료 코드 1을 낸다. 링크 체인을 끝까지 따라가 절대경로를 얻으려면 -f를 붙인다.
자주 쓰는 옵션
| 옵션 | 의미 | 예시 |
|---|---|---|
| (없음) | 링크가 저장한 값 그대로 한 단계만 출력. 상대경로일 수 있다 | readlink /opt/app/current |
| -f | 끝까지 따라가 정규화. 마지막 요소는 없어도 된다(GNU) | readlink -f ./out/new.log |
| -e | -f와 같지만 최종 경로가 실제로 존재해야 성공(GNU) | readlink -e "$p" |
| -m | 아무것도 존재하지 않아도 정규화만 수행(GNU) | readlink -m /a/b/c |
| -n | 끝의 줄바꿈을 붙이지 않는다 | readlink -fn "$0" |
| -q | 에러 메시지를 숨긴다 | readlink -q "$p" |
실전 예제
1) 배포 링크가 실제로 어디를 보는지 확인한다. 옵션 없는 형태와 -f의 차이를 같이 보면 링크 구조가 보인다.
readlink /opt/app/current
readlink -f /opt/app/current
releases/2026-08-25T1130
/opt/app/releases/2026-08-25T1130
2) 실행 중인 프로세스의 실제 바이너리를 확인한다. 패키지를 업데이트했는데 옛 바이너리가 계속 도는지 판별할 때 쓴다(리눅스 전용).
sudo readlink -f /proc/$(pgrep -o nginx)/exe
sudo readlink -f /proc/$(pgrep -o nginx)/cwd
/usr/sbin/nginx
/
3) 삭제됐는데 디스크를 붙잡고 있는 파일을 찾는다. (deleted) 표시가 그 증거다.
sudo ls -l /proc/1234/fd | grep deleted
sudo readlink /proc/1234/fd/3
4) 스크립트가 링크로 호출돼도 자기 실제 위치를 잡는다. /usr/local/bin에 링크를 걸어 배포하는 도구에 필수다.
SELF="$(readlink -f "$0")"
BASE="$(dirname "$SELF")"
echo "running from $BASE"
5) 깨진 심볼릭 링크를 골라낸다. -e는 대상이 없으면 실패하므로 판정에 쓸 수 있다.
for l in /etc/nginx/sites-enabled/*; do
readlink -e "$l" >/dev/null || echo "broken: $l"
done
함정과 주의점
옵션 없는 readlink의 출력은 상대경로일 수 있다. 링크는 대상 경로를 문자열 그대로 저장하므로 readlink /opt/app/current가 releases/2026-08-25T1130처럼 나올 수 있다. 이 값을 그대로 cd나 rsync에 넘기면 현재 디렉터리 기준으로 해석돼 엉뚱한 곳을 가리킨다. 절대경로가 필요하면 무조건 -f다.
macOS·BSD의 readlink는 -f와 -n만 있다. -e, -m은 없고, 더 중요한 차이로 BSD의 -f는 경로가 실제로 존재해야 성공한다. GNU에서는 마지막 요소가 없어도 되므로, 맥에서 짠 "만들 파일의 절대경로 계산" 코드가 리눅스에서는 되는데 맥에서는 실패하거나 그 반대가 된다. 이식성이 필요하면 cd "$(dirname "$0")" && pwd -P 조합을 쓰는 편이 안전하다.
대상이 아니라 링크가 필요한 상황을 구분하라. rm, ls -l, stat은 기본적으로 링크 자체를 다루지만 cp, tar, find는 옵션에 따라 대상을 따라간다. 특히 디렉터리 링크 뒤에 슬래시를 붙이면(current/) 링크가 아니라 대상 디렉터리로 해석된다. 배포 스크립트에서 rm -rf /opt/app/current/를 치면 링크가 아니라 실제 릴리스가 날아간다.
ls -l 출력을 파싱하지 마라. 파일명에 -> 문자열이 들어 있으면 잘라내기가 어긋난다. 기계가 읽을 값은 readlink로 얻어야 한다.
함께 보면 좋은 명령어
- realpath —
readlink -f와 사실상 같은 일을 하며 의도가 더 분명하게 읽힌다. - ln — 링크를 만들고 무중단 교체할 때.
ln -sfn관용구와 짝이다. - lsof —
/proc/PID/fd를 직접 뒤지는 대신 열린 파일을 한 번에 보여 준다.