리눅스 운영체제는 시스템 내 모든 파일에 대해 세 가지 타임스탬프를 기록합니다. 이 타임스탬프들을 활용하면 파일이 마지막으로 언제 수정되었는지 확인할 수 있습니다. 그런데 각 타임스탬프는 정확히 어떤 의미일까요? 파일별로 이 시간들은 어떻게 조회할 수 있을까요? 디렉터리에서도 동일하게 적용될까요?
atime, ctime, mtime에 대한 이해만 있다면 위 질문들에 모두 답할 수 있습니다. 유닉스 파일시스템이 추적하는 바로 이 세 가지 타임스탬프를 통해, 무엇이 언제 변경되었는지 상세히 파악할 수 있습니다.
유닉스의 세 가지 타임스탬프란?
모든 파일에는 세 가지 타임스탬프가 연결되어 있습니다. 리눅스는 에포크(epoch) 이후 경과된 초 단위 시간을 측정하는 유닉스 시간 형식으로 이 값들을 저장하며, 각각은 흔히 atime, ctime, mtime으로 불립니다.
mtime(modified time)은 가장 널리 사용되고 실용적인 타임스탬프입니다. 파일의 내용이 마지막으로 디스크에 기록된 시점, 즉 수정 시간을 나타냅니다.
ctime(change time)은 이름이 비슷하지만 조금 다른 개념입니다. 소유권과 권한 같은 메타데이터 변경 사항을 추적합니다. 최신 리눅스 배포판에서는 파일 이름 변경 시에도 ctime이 갱신됩니다. 또한 파일 내용이 변경될 때도 함께 갱신되므로, 항상 mtime보다 최신 상태를 유지합니다.
세 번째 타임스탬프인 atime(access time)은 파일이 마지막으로 접근(읽기)된 시점을 저장합니다.
디렉터리에 적용되는 타임스탬프
리눅스에서 디렉터리는 본질적으로 해당 디렉터리에 속한 파일들의 목록입니다. 따라서 디렉터리 안에 새 파일을 생성하면 그 디렉터리의 mtime이 갱신됩니다. ls 명령어로 디렉터리 내 파일 목록을 조회하면 접근 시간(atime)이 업데이트됩니다. 그리고 일반 파일과 마찬가지로, 디렉터리의 권한이나 이름을 변경하면 ctime이 갱신됩니다.
생성 시간(creation time)은 없나요?
의외일 수 있지만, 리눅스는 파일의 생성 시간을 따로 기록하지 않습니다. 처음에는 ctime이 creation time(생성 시간)의 약자라고 생각하기 쉽지만, 실제로는 change time(변경 시간)을 의미합니다.
생성 시간을 굳이 저장하지 않는 데에는 이유가 있습니다. 많은 애플리케이션이 파일을 저장할 때마다 매번 처음부터 새로 생성하는 방식을 사용하기 때문에, 생성 시간 정보는 오히려 혼란을 줄 수 있습니다.
타임스탬프 조회 방법
타임스탬프 정보를 확인하는 가장 간단한 방법은 ls 명령어입니다. 기본 긴 형식(long format)으로 출력하면 mtime이 표시됩니다:
$ date
Sat Mar 6 16:57:01 GMT 2021
$ echo "hello, world" > tmp
$ ls -l tmp.txt
-rw-r--r-- 1 ubuntu ubuntu 13 2021-03-06 16:57 tmp
-u 옵션을 사용하면 대신 atime을 표시할 수 있습니다:
$ date
Sat Mar 6 16:59:33 GMT 2021
$ cat tmp
hello, world
$ ls -lu tmp
-rw-r--r-- 1 ubuntu ubuntu 13 2021-03-06 16:59 tmp
$ ls -l tmp
-rw-r--r-- 1 ubuntu ubuntu 13 2021-03-06 16:57 tmp
마지막 줄을 보면 이 파일의 mtime과 atime이 서로 다르다는 것을 확인할 수 있습니다. 마지막으로 -c 옵션을 사용하면 ctime을 볼 수 있습니다:
$ date
Sat Mar 6 17:02:34 GMT 2021
$ mv tmp tmp2
$ ls -lc tmp2
-rw-r--r-- 1 ubuntu ubuntu 13 2021-03-06 17:02 tmp2
$ ls -l tmp2
-rw-r--r-- 1 ubuntu ubuntu 13 2021-03-06 16:57 tmp2
$ ls -lu tmp2
-rw-r--r-- 1 ubuntu ubuntu 13 2021-03-06 16:59 tmp2
이번 예제에서는 세 가지 시간이 모두 서로 다르며 정확함을 확인했습니다. 파일을 수정한 뒤, 접근하고, 그다음 변경(이름 변경)했기 때문입니다.
ls의 대안으로 stat 명령어를 사용할 수 있습니다. 이 명령어는 파일 inode의 저수준 세부 정보를 표시하여, 세 가지 타임스탬프를 한 번에 모두 확인하기 쉽습니다. 직관적이지 않은 -u 옵션을 외울 필요도 없습니다. 앞선 예제와 같은 파일에 대한 출력 결과입니다:
$ stat tmp2
File: `tmp2'
Size: 13 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 327688 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ ubuntu) Gid: ( 1000/ ubuntu)
Access: 2021-03-06 16:59:45.000000000 +0000
Modify: 2021-03-06 16:57:59.000000000 +0000
Change: 2021-03-06 17:02:43.000000000 +0000
타임스탬프 갱신 방법
touch 명령어는 파일의 수정 시간(mtime)과 접근 시간(atime)을 변경합니다. 존재하지 않는 파일을 지정하면 빈 파일을 생성해 주므로, 빈 파일을 만드는 편리한 방법으로도 활용됩니다:
touch tmp
기본적으로 mtime과 atime을 현재 시간으로 설정하며, -t 옵션으로 특정 시간을 지정할 수도 있습니다:
touch -t 202103061200 tmp
-m 옵션과 -a 옵션을 사용하면 각각 mtime 또는 atime만 선택적으로 설정할 수 있습니다:
touch -t 202103061300 -m tmp
단, atime이나 mtime을 설정하면 ctime은 항상 함께 갱신된다는 점에 유의하세요.
타임스탬프 기반 파일 검색 방법
find 명령어 역시 타임스탬프를 활용하는 도구입니다. atime, ctime, mtime을 기준으로 파일을 필터링할 수 있습니다. 예를 들어:
find . -amin 15
위 명령은 정확히 15분 전에 접근한 파일을 찾으며,
find . -mtime -2
위 명령은 최근 2일 이내에 수정된 파일을 찾아줍니다.
리눅스는 모든 파일을 세 번 기록한다
가장 자주 참조되는 타임스탬프는 mtime입니다. 일반적인 파일 목록에 표시되는 날짜와 시간이 바로 mtime입니다. 하지만 나머지 두 타임스탬프 역시 각각의 의미를 제대로 이해하면 매우 유용합니다. 특히 ctime은 '생성' 시간이 아니라 '변경' 시간을 의미한다는 점은 반드시 기억해 두세요.
touch와 stat 같은 명령어는 리눅스 커맨드라인 도구 상자의 든든한 구성원입니다. 이러한 명령어들을 활용하면 새 파일을 빠르게 만들고 관리하면서 리눅스 작업 흐름을 한층 더 효율적으로 개선할 수 있습니다.