Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to write a cross-platform command line that will find all local files on a file system.

My intention is to use the find command, using only POSIX parameters. Is there a way to skip files on remote filesystems, while restricted to only POSIX commands, and no programming?

My current command line is

find -type f -print

but that obviously lists every regular file, not just local ones.

I am aware of the -local flag, but as far as I can tell, it's not POSIX or otherwise part of a cross-platform standard. locate doesn't appear to be cross-platform either. I don't think the -xdev flag is what I'm looking for, either, as I want to search across all locally mounted file systems - if / and /home are both local, and I run find / -xdev -print, find should skip /home (unless I'm misunderstanding stuff).

For what it's worth, the following URLs have been useful resources...

share|improve this question
    
Your observation about -xdev is correct. Have you looked at (ab-)using find's -fstype option at all? –  Anthon Jun 12 '13 at 3:34
    
@Anthon: Yes, I did take a quick look, but <code>-fstype</code> seems very much like rici's suggestion, and would require enumerating all expected file system types in advance... I'm hoping for something more automated :) –  atk Jun 12 '13 at 12:28

2 Answers 2

up vote 1 down vote accepted

I don't believe that there is any way to determine whether a filesystem is remote or local using only POSIX interfaces. POSIX doesn't even mandate a mount command, and all references to file systems, as far as I know, are replete with the words "implementation-defined".

The -local primary to the find command is not much help, since it is only available on Solaris, and it depends on the existence of a configuration file which lists remote filesystem types.

POSIX does mandate a df command and requires a specific output format if that command is used with the -P flag; in that format, there are six space-separated fields, of which the first is the "name of the file system, in an implementation-defined format" and the last is the mount point.

What you need is a list of all the mount points corresponding to local filesystems. Here, I think you're going to have to fall back to a heuristic; which is to exclude filesystem names which "look like" remote filesystems. Some examples:

//...     CIFS (Samba)
host:...  NFS
/afs      AFS

That's not an exhaustive list, and it comes completely without guarantees.

If you then filter those lines out of the output of df and then remove the first five columns, you could then feed the list to the find command with the -xdev primary.

Even if that sounds plausible, there is actually no guarantee that a filesystem is actually "mounted" (see AFS) or that a filesystem is either entirely local or entirely remote (a fuse-based filesystem can arbitrarily redirect individual files). So proceed with caution, is my advice.

share|improve this answer

That -xdev works but maybe not how you'd like, i.e. as stated in POSIX find man: find -xdev runs until FS with differentDevice ID (could be inspected with stat utility or stat() systemcall) is encountered:

e.g. linux:

# stat /home/foo
  File: `/home/foo'
    . . .
Device: fd02h/64770d
  . . .
 # stat /boot/foo
  File: `/boot/foo'
  . . . 
Device: 801h/2049d   
  . . .

Let's find it with -xdev:

# find / -xdev -name foo -print
#

without:

# find / -name foo -print
/home/foo
/boot/foo

   

Inspecting Device ID on Solaris:

# truss -t lstat64 -v lstat64 ls /foo
lstat64("/foo", 0xFFBFFC48)
    d=0x02580000 . . .
# truss -t lstat64 -v lstat64 ls /etc/foo
lstat64("/etc/foo", 0xFFBFFB88)
    d=0x02580000 . . .
# truss -t lstat64 -v lstat64 ls /opt/foo
lstat64("/opt/foo", 0xFFBFFC48)
    d=0x02580004 . . .
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.