Xref: utzoo comp.unix.questions:20649 comp.lang.perl:753 Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!cs.utexas.edu!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.unix.questions,comp.lang.perl Subject: Re: following symbolic links Message-ID: <7448@jpl-devvax.JPL.NASA.GOV> Date: 17 Mar 90 01:41:55 GMT References: <1678@zipeecs.umich.edu> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Distribution: usa Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 138 In article <1678@zipeecs.umich.edu> bguthy@dip.eecs.umich.edu (Bala S. Guthy) writes: : Lately I find myself doing things like : %ls -ld /usr/prog : : and after finding that this is linked to /n/node1/bin, I'd do : : %ls -ld /n/node1/bin : : and so on... : until I get to my destination directory/file. Is there some way to : do this easily, may be a program that prints all the intermediate directories : that are used in getting to a file, across nfs mounts and symbolic links. Ok, I just whipped up a little program called "sl" (for showlinks) that does what you want, in a hopefully convenient format: $ sl dts/libg/dts.h dts/libg/dts.h: dts/libg -> lib_incl_global lib_incl_global/dts.h -> SRC/dts.h SRC -> /u/dts/dts/lib_incl_global /u/dts -> /u8/dts /u8/dts/dts/lib_incl_global/dts.h $ sl /usr/lib/news/compress /usr/lib/news/compress: /usr/lib/news -> ../local/lib/news local/lib/news/compress -> /usr/ucb/compress /usr/ucb/compress $ sl D M P D: D -> src/dist/Todo src -> /s/lwall/src /s/lwall/src/dist/Todo M: M -> src/dist/mcon/Todo src -> /s/lwall/src /s/lwall/src/dist/mcon/Todo P: P -> src/patch/Todo src -> /s/lwall/src /s/lwall/src/patch/Todo $ sl bin/makedist bin/makedist: bin -> vbin vbin/makedist -> ../src/dist/kit/makedist src -> /s/lwall/src /s/lwall/src/dist/kit/makedist $ sl /u/sfoc/lwall/bin/makedist /u/sfoc/lwall/bin/makedist: /u/sfoc -> /u4/sfoc /u4/sfoc/lwall/bin -> vbin vbin/makedist -> ../src/dist/kit/makedist src -> /s/lwall/src /s/lwall/src/dist/kit/makedist It is, of course, written in Perl. Translation to C is left as an exercise for the reader. :-) Larry Wall lwall@jpl-devvax.jpl.nasa.gov #!/bin/sh : make a subdirectory, cd to it, and run this through sh. echo 'If this kit is complete, "End of kit" will echo at the end' echo Extracting sl sed >sl <<'!STUFFY!FUNK!' -e 's/X//' X#!/usr/bin/perl X Xdie "Usage: sl [filenames]\n" unless @ARGV; X X$| = 1; Xchop($cwd = `pwd`) || die "Can't find current directory: $!\n" if $#ARGV > 0; X Xprint "\n"; Xforeach $name (@ARGV) { X @indent = (); X print "$name:\n"; X @path = split(m;/;, $name); X if (@path && $path[0] eq '') { X chdir '/'; X shift @path; X print '/'; X $indent = 1; X } X while (@path) { X $elem = shift @path; X $new = readlink($elem); X if (defined $new) { X print "$elem -> $new\n"; X $new =~ s!^\./!!; X unshift(@path,split(m;/;, $new)); X if (@path && $path[0] eq '') { X chdir '/'; X shift @path; X print '/'; X $indent = 1; X @indents = (); X } X elsif (@path && @indents && $path[0] eq '..') { X $indent = pop(@indents); X chdir '..' || die "\n\nCan't chdir to ..: $!\n";; X shift @path; X print "\t" x ($indent / 8), ' ' x ($indent % 8); X } X else { X print "\t" x ($indent / 8), ' ' x ($indent % 8); X } X } X else { X print $elem; X push(@indents,$indent); X $indent += length($elem) + 1; X if (@path) { X print '/'; X chdir $elem || die "\n\nCan't chdir to $elem: $!\n";; X } X } X } X print "\n\n"; X $indent = 0; X chdir $cwd || die "Can't cd back: $!\n" if $cwd ne ''; X} !STUFFY!FUNK! echo "" echo "End of kit" : I do not append .signature, but someone might mail this. exit