finding the filesystem of a file

Larry Wall lwall at jpl-devvax.JPL.NASA.GOV
Tue Nov 6 08:17:21 AEST 1990


In article <6500 at emory.mathcs.emory.edu> dt at 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 at jpl-devvax.jpl.nasa.gov



More information about the Comp.unix.shell mailing list