Linux 에서 김서방 찾기 - find 편(1)

Joseph Daniel simryang
WIZnet
Published in
10 min readJun 9, 2020

Linux에서 파일이나 사용자를 찾고 싶을 때가 종종 있습니다. 파일을 찾는 find 명령을 배워보도록 합니다.
여기에서는 가장 많이 사용되는 이름, 파일 종류,날짜, 크기 를 기준으로 찾는 방법을 설명합니다. 다른 옵션도 많으나 글이 너무 길어져서 다른 내용은 다음 글에서 나누도록 하겠습니다.
참고로 find v4.7.0 기준 지원하는 전체 옵션은 다음과 같습니다...

operators (decreasing precedence; -and is implicit where no others are given):
( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2
EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2

positional options (always true): -daystart -follow -regextype

normal options (always true, specified before other expressions):
-depth — help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
— version -xdev -ignore_readdir_race -noignore_readdir_race

tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N
-cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME
-ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN
-links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE
-nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN
-readable -writable -executable
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N
-used N -user NAME -xtype [bcdpfls]
-context CONTEXT

actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print
-fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit
-exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;
-execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;

이름으로 파일 찾기

다음과 같은 형태로 명령을 내립니다.

find 찾을_경로 -name ‘찾을_이름_패턴’ 추가옵션들…

‘찾을_이름_패턴’ 안에 공백이나 특수문자가 포함되지 않은 경우 따옴표는 생략해도 됩니다.

find / -name ‘ocf’

/ 포함 하위 디렉토리에서 이름이 ocf 인 파일과 디렉토리를 찾아 상대 경로를 보여줍니다.

find . -name ‘include’

현재 디렉토리(.) 포함 하위 디렉토리에서 이름이 include 인 파일이나 디렉토리를 찾아 상대 경로를 보여줍니다.

find . -name include -type d

현재 디렉토리 포함 하위 디렉토리에서 이름이 include 인 디렉토리만 찾아 상대 경로를 보여줍니다. 여기에서 -type 옵션이 처음 등장했는데요. type에는 다음 값이 올 수 있습니다.

b: block (buffered) special 주로 디스크 장치
c: character (unbuffered) special 드라이버 등에서 사용하는 문자 장치
d: directory 이른바 폴더
f: regular file 일반 파일
p: named pipe (FIFO) named pip 와 아래 socket에 대한 설명은 이 글을 참조하시기 바랍니다. 이 파일들이 존재하는 실물을 보고 싶다면 /run 아래에서 찾아보시기 바랍니다.
s: socket
l: symbolic link 링크 파일. 윈도우의 바로가기 를 생각하시면 됨.

find . -name ‘build’ -type f

현재 디렉토리 포함 하위 디렉토리에서 이름이 build 인 파일만 찾아 상대 경로를 보여줍니다.

grep 을 사용해서 검색 결과를 필터링할 수 있습니다.

원래 grep ‘찾을_패턴’ ‘옵션’ ‘찾을 경로’ 형태로 사용하지만, find 결과를 입력으로 받기 때문에 '찾을 경로'는 작성하지 않습니다.

find . -name ‘include’ | grep iotivity

현재 디렉토리 포함 하위 디렉토리에서 이름이 include 인 파일이나 디렉토리를 찾고 그 경로 중에 iotivity가 포함된 경우만 보여줍니다.

find . -name include -type d | grep -v test

현재 디렉토리 포함 하위 디렉토리에서 이름이 include 인 디렉토리만 찾고 그 경로 중에 test가 포함되지 않은 경우만 보여줍니다.

find . -name Makefile -type f | grep -v ‘test\|examples’

현재 디렉토리 포함 하위 디렉토리에서 이름이 Makefile 이 파일만 찾고 그 경로 중에 test나 examples 가 포함되지 않은 경우만 보여줍니다.

grep 으로 필터링 하기 전에 find 의 -path 옵션으로 경로명을 특정할 수도 있습니다.

find . -path ‘*iotivity*’ -name ‘*lib*’
./test/src/automation/robot/device_lib/src/org/iotivity/test/rfw/common/devicetestlib
./.pkgdir/iotivity/usr/lib
./.pkgdir/iotivity/usr/lib/liboctbstack.so
./ipkg-mipsel_24kc/iotivity/usr/lib
./ipkg-mipsel_24kc/iotivity/usr/lib/liboctbstack.so
./ipkg-mipsel_24kc/iotivity-resource-directory-lib/usr/lib
./ipkg-mipsel_24kc/iotivity-resource-directory-lib/usr/lib/libresource_directory.so

find 변경 날짜로 찾기 -atime, -mtime, -ctime

find 명령에서는 파일이 변경된 날짜로 찾을 수 있습니다. 현재 시간을 기준으로 +1일 -1일 형태로 사용을 합니다. 그런데 사용 가능한 옵션이 atime, mtime, ctime 의 3가지나 됩니다. 무엇을 써야 할까요?

ctime 은 file change time 으로 파일의 속성이 변경된 시간을 가리킵니다.

파일의 속성에는 이름, 그룹, 접근 권한, 데이터 변경(mtime), 기타 속성(lsattr) 등이 포함됩니다.

데이터 수정시에도 속성이 변경된 것으로 처리되어 ctime도 함께 변하게 됩니다.

데이터를 제외한 다른 속성 변경시에는 ctime 만 변경되고 mtime은 변하지 않습니다.

ls -l -c 명령으로 ctime 값을 확인할 수 있습니다. (ls -lc 로 붙여 써도 됩니다.)

mtime 은 file modify time 으로 파일의 데이터 수정 시간으로 파일의 내용이 달라졌을 때 변경되는 값입니다.

파일을 열어서 읽기만 하고 닫는다면 atime 은 갱신되겠지만, mtime은 변경되지 않습니다.

파일을 열어서 값을 수정했다면 mtime은 변경되고 이어서 설명할 ctime도 변경됩니다.

ls -l 명령으로 mtime 값을 확인할 수 있습니다.

atime 은 file access time 으로 파일이 어떤 명령이나 스크립트 등에 의해 열리거나 읽혀질 때 변경되는 값입니다.

cat, head, tail, sort, grep, vim, nano 등등의 명령 또는 프로그램에 의해 해당 파일의 atime이 바뀌게 됩니다.

ls -l -u 명령으로 atime 값(날짜와 시간 값)을 확인할 수 있습니다. ( ls -lu 로 붙여 써도 됩니다)

이 부분 테스트하다가 글 작성을 완료하지 못하고 잠시 정체되었네요. 문제는 atime이 의도한대로 cat 등의 동작에 갱신되지 않는 점이었습니다. 왜 그럴까 하면서 찾아보다가 이유를 찾았습니다. atime을 갱신하는데에 성능 비용이 많이 소모되어 리눅스 커널 v2.6.30 부터는 파일시스템 마운트 옵션을 relatime 으로 바꾸었고 이 방식은 본래의 atime 변경 방식을 사용하지 않고 mtime이나 ctime 이 atime 보다 미래인 경우에만 atime을 바꾸도록 변경되었습니다. find 사용하실 때 atime 옵션은 사용하지 않으시는게 좋으실 것 같습니다.

시간 옵션 사용 예

find . -mtime 1

파일 데이터가 수정된 지 1일이 경과된 파일만 검색합니다.

이 1일은 시간 기준입니다. 하루가 24시간이니까 24시간이 지난 시점부터 48시간 전까지를 1일로 보고 있습니다.

-mtime 1 은 1x24 로 24~48 시간 까지 해당됩니다. -mtime 2 는 48~72 시간까지겠죠?

1대신 n ≥ 0 인 n이라면 n * 24시간 ≤파일 시간≤ (n + 1) * 24 시간 을 만족하는 모든 파일을 찾습니다.

n 에 음수 부호 - 를 붙일 수도 있습니다.

find . -mtime -1

파일 데이터가 수정된 지 1일(1x24 시간보다 더 오래 지난 시간)이 안된 모든 파일만 검색합니다. 1이면 만 1일이라는 느낌이라면 -1은 만1일이 안된 모든 파일입니다.

1 대신 n≥0 인 n이라면 n * 24 시간 보다 작은 시간이 경과된 모든 파일을 찾습니다.

만약 - 대신 +1을 쓴다면 의미가 반대로 되겠죠?

find . -mtime +1

파일 데이터가 수정된 지 만 1일보다 큰 시간이 경과된 파일만 검색합니다.

1대신 n 이라면 n * 24 시간 보다 큰 시간이 경과된 파일을 찾습니다.

파일 크기로 찾기

find . -size 50

파일 데이터가 50인 파일을 찾는데 문제는 단위가 우리가 생각하는 단위가 아닙니다!
위의 예처럼 아무것도 추가하지 않고 숫자만 쓰면 기본값인 block 으로 해석합니다.
보통 block 은 512Byte(이하 B) 입니다.
이 값이 시스템에 따라 달라질까 싶어서(하드 디스크 기본 block 크기랑 동일하지 않을까 하는 생각에서 sudo dumpe2fs /dev/sda1 | grep “^Block size” 로 확인해봄) 테스트 해봤지만 동일한 것으로 보입니다(이 부분은 ls와는 다르게 동작).
어쨌든 1로 하면 파일 크기가 1B인 파일을 찾는 것이 아니라 1B≤파일 크기<512B 를 만족하는 파일을 찾습니다.
크기가 딱 1B인 파일을 찾으려면 -size 1c 라고 옵션을 줘야 합니다. 지원하는 단위는 다음과 같습니다.

b: 512B 단위 (기본값임)
c: 1B 단위
w: 2B 단위
k: 1024B 단위
M: 1024kB 단위
G: 1024MB 단위

주의할 것이 -size 옵션도 -mtime 옵션처럼 -, + 를 붙여서 미만, 초과를 지정할 수 있지만 1M 보다 작은 파일을 찾고 싶다고 -1M이라고 쓰면 M을 단위로 보고 1보다 작은 0인 크기의 파일만 찾게 됩니다.

이런 점만 빼면 -mtime 과 유사합니다.

find . -size 1M

파일 크기가 1B≤파일 크기≤1048576B 를 만족하는 파일만 찾습니다.

find . -size +1M

파일 크기가 1048576B 보다 큰 파일을 모두 찾습니다.

음수 - 가 붙으면 단위 앞의 값이 1이 아닌 경우에는 해당 값보다 작은 크기의 파일을 모두 찾고 1이면 파일 크기가 0인 파일만 찾습니다.

find . -empty

파일 크기가 0인 파일을 찾고 싶으면 -1과 같은 표현도 되지만 위처럼 -empty 라고 명시적으로 써주면 찾는 의도가 명확해집니다.

이 정도만 해도 왠만한 파일은 다 찾을 수 있습니다. 다음 글에는 리눅스 파일 시스템의 중급 정도의 지식을 갖추고 있을 때 찾을 수 있는 나머지 옵션들에 대해 다뤄보겠습니다.

--

--