2010. 11. 16. 08:56

Ububtu/Linux에서 File 검색(Search)하기

Ubuntu는 file system에 모든 file에 대한 DB를 유지/관리합니다.(/etc/updatedb.conf등 몇몇 예외는 있습니다.) locate 명령은 DB를 검색하는데 쓰입니다. 결과는 file system에서가 아니라 DB를 통해 검색하여 즉각적으로 보고됩니다. locate가 가능하기전에는 대부분의 linux user는 find 명령을 이용하여 file system의 file을 검색하였습니다. 여기에서는 locate와 find를 모두 다루기로 합니다.


locate로 file 찾기

DB는 file sytem에서 모든 node와 명령의 이름을 가지고 있기 때문에, 당신은 locate를 명령, device, man page, data files, 혹은 file system에서 이름으로 구분되는 모든 것을 찾는데 사용할 수 있습니다. 다음의 예를 보십시요.
$ locate e1000
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000e
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000/e1000.ko
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000e/e1000e.ko
/usr/src/linux-headers-2.6.32-21/drivers/net/e1000
/usr/src/linux-headers-2.6.32-21/drivers/net/e1000e
/usr/src/linux-headers-2.6.32-21/drivers/net/e1000/Makefile
/usr/src/linux-headers-2.6.32-21/drivers/net/e1000e/Makefile
/usr/src/linux-headers-2.6.32-21-generic/include/config/e1000.h
/usr/src/linux-headers-2.6.32-21-generic/include/config/e1000e.h
위 예에서, e1000.ko와 e100.kr kernel 모듈과 같이, 두가지 버전을 찾아줍니다. locate는 -i 옵션을 사용하지 않으면, case-sensitive로 동작합니다.
$ locate -i itco_wdt
/lib/modules/2.6.32-21-generic/kernel/drivers/watchdog/iTCO_wdt.ko
slocate package(혹은 linux 배포판에서 mlocate)는 하루에 한번 file의 DB를 update를 실행하는 job을 cron하는 것을 포함합니다.

바로 DB를 update하고 싶다면, 다음과 같이 수동을 명령을 수행하면 됩니다.
$ sudo updatedb


find로 file의 위치 구하기

locate 이전의 시대는 find 명령으로 file을 찾았습니다. locate는 보다 빠르게 동작하지만, find는 이름 뿐만 아니라 attribute와 같은 것을 대상으로 하여 보다 강력한 다양한 옵션을 제공합니다.

아래 예제는 e100에 대해 root file system(/)을 recursive하게 찾습니다.
$ find / -name "e100*" -print | more
/lib/firmware/2.6.32-21-generic/e100
/lib/firmware/e100
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000/e1000.ko
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000e
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000e/e1000e.ko
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e100.ko
find: `/proc/tty/driver': Permission denied
find: `/proc/1/task/1/fd': Permission denied
find: `/proc/1/task/1/fdinfo': Permission denied
...
/usr/src/linux-headers-2.6.32-21-generic/include/config/e1000.h
/usr/src/linux-headers-2.6.32-21-generic/include/config/e100.h
find: `/lost+found': Permission denied
find: `/etc/chatscripts': Permission denied
find: `/etc/ssl/private': Permission denied
find: `/etc/cups/ssl': Permission denied
find: `/etc/ppp/peers': Permission denied
find: `/root': Permission denied

find를 일반 user로 실행하는 것은 권한 접근 오류를 많이 유발 시킬 수 있습니다. 다음과 같이 접근할 수 없는 directory에 filter를 걸 수 있습니다.
 $ find / -name e100 -print 2>&1 | grep -v "Permission denied"
/lib/firmware/2.6.32-21-generic/e100
/lib/firmware/e100
$ find / -name e100 -print 2> /dev/null
/lib/firmware/2.6.32-21-generic/e100
/lib/firmware/e100

find는 case-sensitive인데에 다가, exact match이기 때문에 e100.ko같은 것을 찾아주진 못합니다. 그래서, 아래와 같이 regular expression을 사용합니다.
$ find / -name "e100*" -print 2> /dev/null
/lib/firmware/2.6.32-21-generic/e100
/lib/firmware/e100
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000/e1000.ko
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000e
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e1000e/e1000e.ko
/lib/modules/2.6.32-21-generic/kernel/drivers/net/e100.ko
/usr/src/linux-headers-2.6.32-21/drivers/net/e1000
/usr/src/linux-headers-2.6.32-21/drivers/net/e1000e
/usr/src/linux-headers-2.6.32-21-generic/include/config/e1000e.h
/usr/src/linux-headers-2.6.32-21-generic/include/config/e1000.h
/usr/src/linux-headers-2.6.32-21-generic/include/config/e100.h

또한, timestamp로 검색할 수 있습니다. 다음은 ~ directory에서 과거 2분동안 access된 것을 보여줍니다.
$ touch errors.txt
$ find ~ -amin -2 -print
/home/greenfish/errors.txt

그리고, ~ directory에서 60일동안 access하지 않은 파일을 찾을 수 있습니다.
$ find ~ -atime +60

-type d 옵션을 사용하면 directory를 검사합니다. 다음은 /etc의 모든 하부를 찾고, stderr를 bit bucket(/dev/null)로 보냅니다.
$ find /etc -type d -print 2> /dev/null
/etc
/etc/wpa_supplicant
/etc/ufw
...
/etc/fonts
/etc/fonts/conf.avail
/etc/fonts/conf.d

아래 명령은 750과 match되는 권한을 가진 /sbin을 찾습니다.
$ find /sbin/ -perm 750 -print

exec 옵션은 강력한 도구로, find 명령으로 실행할 수 있게 해줍니다. 다음의 명령은 greenfish user가 소유하고 있는 /var를 검색하고 ls -l 명령을 각각 실행합니다.
$ find /var -user greenfish -exec ls -l {} \; 2> /dev/null
total 4
-rw-r--r-- 1 greenfish greenfish 21 2010-10-03 20:28 dmrc
-rw-r--r-- 1 greenfish greenfish 21 2010-10-03 20:28 /var/cache/gdm/greenfish/dmrc

다른방법으로, 다음과 같이 xargs를 이용할 수 있습니다.

$ find /var -user greenfish -print 2> /dev/null | xargs ls -l
-rw-r--r-- 1 greenfish greenfish   21 2010-10-03 20:28 /var/cache/gdm/greenfish/dmrc

/var/cache/gdm/greenfish:
total 4
-rw-r--r-- 1 greenfish greenfish 21 2010-10-03 20:28 dmrc


위 두개의 큰 차이점은 성능이라 할 수 있습니다. find -exec는 찾을 때 마다 각각 ls를 실행하고, xargs는 보다 효과적으로 샐행되는데 ls 명령으로 한번에 결과를 전달하게 됩니다.

검색 기준을 부정하려면 !를 사용합니다.
다음 예는 root group에 소유되지 않은 모든 정규 file을 나열하고 ls -l을 수행합니다.
$ find / ! -group root -type f -print 2> /dev/null | xargs ls -l
...
-rw-r----- 1 syslog    adm           10574 2010-10-18 16:43 /var/log/user.log.1
-rw-rw-r-- 1 root      utmp          87168 2010-10-19 04:49 /var/log/wtmp
-rw-r--r-- 1 avahi     avahi             4 2010-10-18 16:43 /var/run/avahi-daemon/pid
-rw-rw-r-- 1 root      utmp           2688 2010-10-19 04:49 /var/run/utmp

다음은 다른 이들에 의해 writable하지 않은 file을 나열하고, ls -l을 수행합니다.
$ find /sbin/ -type f ! -perm /o+w -print | xargs ls -l
-rwxr-xr-x 1 root root     5496 2009-12-25 00:26 /sbin/acpi_available
-rwxr-xr-x 1 root root     5553 2010-01-28 16:01 /sbin/alsa
-rwxr-xr-x 1 root root    84192 2010-03-28 16:02 /sbin/alsactl
-rwxr-xr-x 1 root root    10557 2010-03-28 16:02 /sbin/alsa-utils
...
-rwxr-xr-x 1 root root    13800 2010-03-22 10:51 /sbin/wipefs
-rwxr-xr-x 1 root root     1910 2010-03-06 22:24 /sbin/wpa_action
-rwxr-xr-x 1 root root    39344 2010-03-06 22:24 /sbin/wpa_cli
-rwxr-xr-x 1 root root   515044 2010-03-06 22:24 /sbin/wpa_supplicant

file size에 의한 찾기는 어떤 것이 hard disk를 차지하고 있는지를 쉽게 확인시켜 줍니다. 다음의 명령은 10MB 이상의 파일을 나열하고, 가장 작은 용량부터 나열(ls -lS)하고 /tmp/bigfiles.txt에 보고합니다.
$ find / -xdev -size +10M -print | xargs ls -lS > /tmp/bigfiles.txt
xdev는 검색할 directory의 file system에서만 찾고, 다른 mount된 file system은 검색을 배제하도록 합니다. 이는 /proc directory나 다른 원격 mount된 file system등에서 찾는데 도움을 주며, 역시 local mount된 file system에서만 찾는데도 도움을 줍니다.


file을 찾는데 필요한 다른 명명

다른 명령으로는 whereis와 which가 사용됩니다.
$ whereis man
man: /usr/bin/man /usr/local/man /usr/share/man /usr/share/man/man7/man.7.gz /usr/share/man/man1/man.1.gz
$ which ls
/bin/ls

whreris 명령은 명령 뿐만 아니라 man page, 명령과 연계된 conf 파일들을 함께 검색하는데 도움을 줍니다. 위 예에서 man 단어에 대한 find 결과에서 실행 파일, 설정 파일 그리고 man 설명을 위한 man page도 함께 나열해 줍니다. which 명령은 ls 명령의 실행 경로를 알려줍니다. which 명령은 PATH 상의 실제 실행될 경롤르 찾는데 도움을 줍니다.

$ dpkg-query -S `which ps`
procps: /bin/ps