dt@mathcs.emory.edu (Dave Taylor {guest}) (11/06/90)
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. for the file /u/foo/bar/new, the output should be "/u/foo/bar" for the file /u/foobar/new, the output should be "/u" The reason for this is because I backup several filesystems on one tape and I need to know which filesystem to look in as I search through my log files. Thanks in advance for all your help. --david -- ------- ------- David E. Taylor, OMSS UNIX Development // Operation Mobilization USA AT&T: (404) 631-0432 +====+ UUCP: {decvax, sun!sunatl, gatech}!emory!om!dt FAX: (404) 631-0439 +====+ Internet: dt%om.uucp@mathcs.emory.edu
dt@mathcs.emory.edu (Dave Taylor {guest}) (11/06/90)
> 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?? --david -- ------- ------- David E. Taylor, OMSS UNIX Development // Operation Mobilization USA AT&T: (404) 631-0432 +====+ UUCP: {decvax, sun!sunatl, gatech}!emory!omusa!dt FAX: (404) 631-0439 +====+ Internet: dt%omusa.uucp@mathcs.emory.edu
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/06/90)
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
cpcahil@virtech.uucp (Conor P. Cahill) (11/06/90)
In article <6495@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 Maybe not the fastest, but it will work: lookup=path_to_look_up len=0 filesys=`(mount; echo done) | while read fs junk do if [ "x$fs" = "xdone" ]; then echo $lfs fi tlen=\`expr "x$lookup" : "x$fs"\` if [ "$tlen" -gt "$len" ]; then lfs="$fs" len="$tlen" fi done` echo "$filesys" -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
dcon@cbnewsc.att.com (david.r.connet) (11/07/90)
In article <10243@jpl-devvax.JPL.NASA.GOV>, lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: > 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. > > If you happen to have perl handy, either of the following will work > (presuming you have no symbolic links): [some perl examples] > > 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: [shell example] On some systems, /etc/mtab is known as /etc/mnttab. Also, on SVR4 systems, [I know this doesn't help you Dave, just throwing out some additional things] you can use the statvfs() call. int statvfs(char *path, struct statvfs *buf); The field buf->f_fstr will give the filesystem name. Dave Connet dcon@iwtng.att.com
guy@auspex.auspex.com (Guy Harris) (11/08/90)
>Also, on SVR4 systems, [I know this doesn't help you Dave, just throwing >out some additional things] you can use the statvfs() call. > int statvfs(char *path, struct statvfs *buf); >The field buf->f_fstr will give the filesystem name. Assuming that's what the particular file system type puts there. The manual page describes it as a "file-system specific string", so a file system type could put a string giving its author's birthday there if it chooses to....
jeff@onion.pdx.com (Jeff Beadles) (11/08/90)
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 Well, I didn't see the entire question, but if you're trying this from the shell (This is comp.unix.shell, ya know... :-), and have a newer version of df, then you might be able to do something like this: % df /usr2/jeff/.newsrc Filesystem kbytes used avail capacity Mounted on /dev/ds08a 279922 32566 219363 13% /usr2 From that, you could do something like: ------------------------snip here----------------------------- #!/bin/sh if [ -z "$1" -o ! -r "$1" -o $# -ne 1 ] ; then echo "Usage: $0 filename" exit 1 fi ## Do the df, print the 6th field of a line starting with '/'. df $1 | awk '/^\// { print $6 } ' exit 0 ------------------------snip here----------------------------- Of course if your output of df is different, you may have to change the $6 to something else. If you're trying to do this from 'C', then look at the statfs(2) man page. Hope this helps! -Jeff -- Jeff Beadles jeff@onion.pdx.com
cbp@icc.com (Chris Preston) (11/10/90)
In article <1990Nov06.021023.11941@virtech.uucp> cpcahil@virtech.UUCP (Conor P. Cahill) writes: >In article <6495@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 > >Maybe not the fastest, but it will work: [shell script deleted] or an awk solution mount | awk 'BEGIN{ # file is defined so as to minimize confusion by useing $1 in substr() # also, I believe that this should be $3 in Xenixland file="'$1'" if ( file == "" ){ print "Usage: '$0' <filename>" exit } } { lenfsnam=length($1) if ( $1 == substr(file,0,lenfsnam) ){ list[lenfsnam]=$1 if ( lenfsnam > closematch ) closematch=lenfsnam } } END{ if ( closematch ) print list[closematch] else #totally optional - should take out if meant for pipe usage print "no match" }' cbp --- Kurt Waldheim to Saddam Hussein: "Saddam, I knew Hitler, and believe me, you're no Adolf Hitler."