🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix.shell
Article #1715

Re: finding the filesystem of a file

#1715
From: Larry Wall
Date: Mon, 05 Nov 1990 21:17
70 lines
2716 bytes
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
Technical Details
Message-ID: <10243@jpl-devvax.JPL.NASA.GOV>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rutgers!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall
References: <6495@emory.mathcs.emory.edu> <6500@emory.mathcs.emory.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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