Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Make the locate command ignore certain directories UNIX
I currently have a backup Jaguar partition on a separate drive and a "Previous Systems" directory from the Archive and Install of Panther that I'm not ready to get rid of yet. I use the command line tool locate often and was getting very tired of it listing everything it found from my backup drive and my Previous System directory. I'd have to either wade through the output looking for the correct items, or rig up a pipe to grep to get only the items I was looking for. I'm not sure if anyone but me has this problem, but this is how I fixed it.

I made a change in /usr/libexec/locate.updatedb so that the locate database won't store anything found in either the "/Volumes" directory (which leads to the backup drive) or the "/Previous Systems" directory.

Read the rest of the hint for the how-to...

Basically I just added -regex "/Volumes" -o and -regex "/Previous Systems" -o to the find command in the locate.updatedb script. You can manually change those dirs to anything you want and add more dirs to be ignored -- just make sure you add the "or" flag (-o) to the logic.

Find the following in /usr/libexec/locate.updatedb (around line 62):

find ${SRCHPATHS} \( ! -fstype local -o -fstype fdesc -o -fstype devfs \) -a \
  -prune -o -print | \
  tr '/' '\001' | \
  (sort -T "$TMPDIR" -f; echo $status > $errs) | tr '\001' '/' > $filelist
and add the following code between find ${SRCHPATHS} ( and ! -fstype local:

-regex "/Volumes" -o -regex "/Previous Systems" -o \
so that the new code looks like this:

find ${SRCHPATHS} \( -regex "/Volumes" -o -regex "/Previous Systems" -o \
  ! -fstype local -o -fstype fdesc -o -fstype devfs \) -a \
  -a -prune -o -print | \
  tr '/' '\001' | \
  (sort -T "$TMPDIR" -f; echo $status > $errs) | tr '\001' '/' >
Then to update your locate database right away, run the following command in Terminal:

sudo /usr/libexec/locate.updatedb
    •    
  • Currently 1.80 / 5
  You rated: 2 / 5 (5 votes cast)
 
[14,650 views]  

Make the locate command ignore certain directories | 23 comments | Create New Account
Click here to return to the 'Make the locate command ignore certain directories' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Make the locate command ignore certain directories
Authored by: klktrk on Nov 14, '03 01:45:32PM

Following your hint gives me this error output when I try to run the revised script:

find: : unknown expression primary
csh: !: Command not found.




[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: klktrk on Nov 14, '03 01:55:53PM

Here's my code, by the way:

find ${SRCHPATHS} \( -regex "/Volumes" -o -regex "/Previous Systems" -o \
! -fstype local -o -fstype fdesc -o -fstype devfs \) -a \
-prune -o -print | \
tr '/' '\001' | \
(sort -T "$TMPDIR" -f; echo $status > $errs) | tr '\001' '/' > $filelist



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: klktrk on Nov 14, '03 02:06:10PM

You know what's weird about the code is that you don't have a ! (not) operator in front of your regexs. Aren't you saying YES then to including /Volumes and /Previous Systems?



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: ryo on Nov 14, '03 02:19:19PM

hmm, try escaping the "!" so it reads "\! fstype local" this may be a csh vs. tcsh thing?

also, the way the logic goes in the find arguments is find will only print the results that don't match all the other arguments. The 'and' binds tighter than the last 'or'.

In other words, if a file matches the dirs you added to the statement, then find will -prune it (not descend into the directory and waste time) and won't print the result. The same goes if any of the other args in the parentheses evaluate to true: they'll be '-prune'ed and then ignored.



[ Reply to This | # ]
Very bad hint
Authored by: Novajo on Nov 14, '03 03:56:21PM

Modifying system files is never a good idea, especially since there is an option to be passed at the command line to skip certain directories: it is --prune-path, as in:

/usr/libexec/locate.updatedb --prune-path="/Volumes /Previous\ System/"

See man locate.updatedb



[ Reply to This | # ]
doh!
Authored by: ryo on Nov 14, '03 04:43:05PM

I stand corrected: Use the method Navajo mentions.

In my defense, in figuring out how to exclude these directories I tried 'man locate' which told me nothing about excluding directories and nothing about creating a configuration file for locate.updatedb (/etc/locate.rc), and 'locate locate' to find any files associated with 'locate' and since there's no /etc/locate.rc on my machine I found no mention anywhere of an alternate way of controlling locate.updatedb. Nothing is even mentioned in the source of locate.updatedb.



[ Reply to This | # ]
Very bad hint
Authored by: klktrk on Nov 14, '03 06:29:36PM

Okay, so you don't think we should modify system files.... Then how do we pass the parameters you suggest? For example, the locate.updatedb command is run by the periodic weekly script. If we want to change which directories are parsed, then we would have to modify THAT system file.

Is it our system, or Apple's? I thought the whole point of UNIX was that you could make it do anything you want.

Or are you going to tell me I'm not "allowed" to rebuild my kernel, or build my own version of different utilities if I feel like it?



[ Reply to This | # ]
Very bad hint
Authored by: gmackenz on Nov 14, '03 06:54:04PM

Modifying a cron job is much safer than modifying system files or doing crazy things like I did once, where I compiled my own version of tcsh on my work solaris server once and set it up to use that spanky-fine tcsh as the default shell for all users (including root). Clever me, no?

A year later I upgraded the Solaris OS and the compiled tcsh was either removed accidently or was incompatible. Needless to say I could no longer log in remotely or locally after a system reboot. It took me and the system adminstrators a day or so to figure out what a bad boy I had been :(

MORAL:

Make changes to your local environmentals and don't monkey with system files/settings!



[ Reply to This | # ]
Very bad hint
Authored by: bluehz on Nov 14, '03 08:48:39PM

Does anyone else ever see the "The locate db is over 8 days old" msg when using locate. I like to use locate - but it seems the db is not being updated. I leave my machine on 24/7 so I know the crontasks are running - but it always says "over 8 days old"



[ Reply to This | # ]
Very bad hint
Authored by: cilly on Nov 15, '03 07:23:45AM

I guess you did an upgrade install? :-)

---
cilly



[ Reply to This | # ]
Very bad hint
Authored by: Novajo on Nov 16, '03 12:08:13AM

Sure it's your system and you do what you want. If you want to modify scripts, it is your right to do so. I just wouldn't do it if not necessary. And there is a significant difference between modifying system configuration files in /etc versus scripts in /usr/bin and others. For instance, there are hooks to do daily and weekly jobs that are already provided: create daily.local or weekly.local to add you own stuff to the cron job.

That said, the man page is out of sync and the suggestion I made actually does not work as mentionned elsehwere on this page, which blows because an up-to-date locate script is very powerful.

So go nuts: modify locate.updatedb. Personnally, I would instead get a newer version and install in /usr/local/.



[ Reply to This | # ]
Re: Very bad hint
Authored by: flunkedflank on Nov 15, '03 01:46:22AM

I see --prunepaths in the man page, but are you sure that it actually works? Looking at the source for locate.updatedb, I don't see it processing any command line arguments. I think the man page must be out of sync for some reason. (I'm using Panther.)



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: klktrk on Nov 14, '03 02:18:21PM

Okay, so the code has to look like this ( The \! has to go before the parentheses).

Like so:

find ${SRCHPATHS} \! \( -path '/Volumes*' -o -path '/Previous Systems*' \
-o -fstype local -o -fstype fdesc -o -fstype devfs \) -a \
-prune -o -print | \
tr '/' '\001' | \
(sort -T "$TMPDIR" -f; echo $status > $errs) | tr '\001' '/' > $filelist



This seems to be working.



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: Mikey-San on Nov 14, '03 02:03:21PM

This is easy with grep:

locate file | grep -v "/Previous*"

This will invert the search by grep and exclude what you want. I think. Heh.



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: klktrk on Nov 14, '03 02:07:48PM

Much better to not have locate have to deal with files you don't want found in the first place. Why take up the extra disk space, and use the extra processing time during update of the locate database?



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: cilly on Nov 15, '03 07:40:29AM

Hm, I feel sad to tell you that there is an easier way, since you spent surely a lot of time in editing the system file. But first of all, modifying a system file is not recommended, especially if there is a config file which will make things work for you.

First you should have read the manpages:

man locate.updatedb
Then you would have seen that the locate database config file is:
/etc/locate.rc
in the manpage you also will see this:
---prunepaths   Sets the list of parent directories that should not be go in the database.
and the usage of the command:
/usr/libexec/locate.updatedb [---tmpdir=dir] [---fcodes=dbfile] [---searchpaths='dir1 -dir2...'] [---prunepaths='dir1 -dir2...'] [---filesystems='type1 -type2...']
I recommend creating a locate.rc file in /etc and specifying the prunepaths there.

---
cilly

[ Reply to This | # ]

Make the locate command ignore certain directories
Authored by: bluehz on Nov 15, '03 08:24:22AM
thx cilly for that info on /etc/locate.rc. It does sound like that shoudl be the place to put pruned dir. Can you give us a little info on the format for the /etc/locate.rc file. By default there is no locate.rc file so I am not sure of the syntax of this file. Quick search on Google yields this info - looks like it could be used (not this is for OpenBSD - DO NOT USE WITHOUT MODIFYING):
#       $OpenBSD: locate.rc,v 1.1 1996/08/17 01:30:25 michaels Exp $
#
# /etc/locate.rc -  command script for updatedb(8)
#
# $Id: locate.rc,v 1.1 1996/08/17 01:30:25 michaels Exp $

# temp directory
TMPDIR="/var/tmp"

# the actual database
FCODES="/var/db/locate.database"

# directories to be put in the database
SEARCHPATHS="/"

# directories unwanted in output
PRUNEPATHS="/tmp /usr/tmp /var/tmp /a /b /c /d /kern /proc /portal /p /fd /mnt /mnt2 /cdrom /root /u /obj /usr/obj /var/obj"

# filesystems allowed. Beware: a non-listed filesystem will be pruned
# and is the SEARCHPATHS starts in such a filesystem locate will build
# an empty database
#
# be carefully if you add 'nfs'
FILESYSTEMS="local" 


[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: cilly on Nov 15, '03 10:21:22AM
This looks good!

I would use the full path: /private/var/db/locate.database Just to make sure it will work if the alias is broken.

You only need to add i.e. /Volumes to the prunepath value, or any other path you want to excempt.

---
cilly

[ Reply to This | # ]

Make the locate command ignore certain directories
Authored by: jyu on Nov 15, '03 05:29:09PM

Where does /etc/locate.rc come from? I have 10.2 and 10.3, but couldn't find this file on either system. I think that's the reason the hint poster didn't use it.



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: bluehz on Nov 15, '03 06:32:54PM

The locatedb.rc does not exist and as a previous poster noted - I don't think the version of locate included with OS X or Fink is taking into acct the locatedb.rc by default. I tried the format above and told it to prune my "Previous Systems" dir and it did not. So it looks like the rc is not being used. I don't even see a cmdline switch to get locate.updatedb to read in teh configs from locatedb.rc.



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: cilly on Nov 15, '03 08:00:40PM

do man locate.updatedb and you will see it is locate.rc !

---
cilly @ http://www.cilly.dyndns.org/



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: bluehz on Nov 15, '03 10:49:56PM

Actually locate.rc is what I used - I just typed it wrong above. Still not observing my prefs in /etc/locate.rc



[ Reply to This | # ]
Make the locate command ignore certain directories
Authored by: flunkedflank on Nov 15, '03 02:48:05PM

yes, but if you actually read locate.updatedb (which is a shell script) you see that it doesn't account for these command line arguments anywhere. I don't see how it could possibly use them. I think the man page must be out of sync with the installed version.



[ Reply to This | # ]