Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.unix.shell Subject: Re: finding the filesystem of a file Keywords: filesystem search find file Message-ID: <10243@jpl-devvax.JPL.NASA.GOV> Date: 5 Nov 90 21:17:21 GMT References: <6495@emory.mathcs.emory.edu> <6500@emory.mathcs.emory.edu> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Distribution: usa Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 70 In article <6500@emory.mathcs.emory.edu> dt@mathcs.emory.edu (Dave Taylor {guest}) writes: : > Curious to know if anyone can tell me the fastest way to find out which : > filesystem a given file is on if the entire pathname is given. I have only : > 5 filesystems but I'm stumped as to on how to make sure that I always match : > the file with the appropriate filesystem. i.e. if the files are /u/foo/bar/new : > and maybe /u/foobar/new AND the filesystems are /u, /u/foo, and /u/foo/bar. : : : Just for clarification, this on SCO Xenix 2.3.2, so doing a df on the directo- : ory of file will NOT work, but thanks to those who replied so quickly. HELP?? If you happen to have perl handy, either of the following will work (presuming you have no symbolic links): #!/usr/bin/perl $file = shift; (($filedev) = stat($file)) || die "Can't stat $file: $!\n"; foreach $comp (split(m#/#,$file)) { $path .= "$comp/"; # try left to right ($dev) = stat($path); if ($dev == $filedev) { chop($path); print "$path\n"; exit; } } print $file; or #!/usr/bin/perl $file = shift; (($filedev) = stat($file)) || die "Can't stat $file: $!\n"; $shortest = $file; while ($file =~ s#(.*)/.*#$1#) { # try right to left ($dev) = stat($file || '/'); if ($dev != $filedev) { print $shortest,"\n"; exit; } $shortest = $file; } print "/\n"; The first one is probably a little faster on the average, since it has to stat shorter names, and most mount points come early in the average path name. In the absence of perl, your best bet will probably be to look for the longest match from /etc/mtab, presuming you have a reasonable one. The following works on my /etc/mtab, but is suboptimal: #!/bin/sh file="$1" ( echo 'case "'"$file"'" in' awk '{print $2}' /etc/mtab | sort -r | sed 's#\(.*\)#\1*) echo "\1";exit;;#' echo 'esac' ) | sh You could, for instance, lose the awk and sort on the second field, and pick out the second field with the sed. No doubt Dan will tell me a way to do the whole thing with sort... :-) Larry Wall lwall@jpl-devvax.jpl.nasa.gov