bitbug@lonewolf.sun.com (James Buster) (01/03/90)
I have the following script, called make_symlinks: #!/usr/local/bin/perl # make_symlinks: each argument is 'oldfile newlink' while (<>) { chop; $limit = (@array = split); for ($i = 0; $i < $limit; $i++) { symlink(@array[$i], @array[++$i]); } } This script takes argument pairs (from standard input usually) of the form 'oldfile link', and makes symbolic links to 'oldfile'. Its primary purpose is the create clone symlink trees of a directory hierarchy. I would like any pointers on how this script may be optimized. Here is how this script is invoked (from a much larger /bin/sh script: THERE=`(cd $1; pwd)` type_arg="! -type d" (cd $THERE; find . $type_arg -print | sed -e 's/^..//') | \ sed -e "s/'/'\\\\''/" -e "s#.*#$THERE/& &#" | $BIN/make_symlinks I would also appreciate any pointers on how this these sh pipelines can be optimized. Thanks for your support (and perl!). -- --------------------------------------------------------------------- James Buster (Domain) bitbug@lonewolf.ebay.sun.com Mad Hacker Extraordinaire (UUCP) ...!sun.com!lonewolf!bitbug ---------------------------------------------------------------------
hakanson@ogicse.ogc.edu (Marion Hakanson) (01/04/90)
In article <BITBUG.90Jan2225503@lonewolf.sun.com> bitbug@lonewolf.sun.com (James Buster) writes: >I have the following script, called make_symlinks: >. . . >This script takes argument pairs (from standard input usually) of the >form 'oldfile link', and makes symbolic links to 'oldfile'. Its primary >purpose is the create clone symlink trees of a directory hierarchy. >I would like any pointers on how this script may be optimized. >Here is how this script is invoked (from a much larger /bin/sh script: >. . . I have a tool, all in Perl-3.0, which does exactly this task. It builds the complete clone directory (we call them "shadow" directories here), including making the subdirectories themselves, as well as copying any symlinks in the original (as opposed to making a symlinks to symlinks). The one "different" thing it does is that all the symlinks are made relative to a single toplevel link in the shadow directory. That toplevel symlink then points at the "real" directory, and can be changed to retarget the shadow directory without rebuilding the whole thing. It's also an advantage over symlinks to full paths, which can sometimes get too long for "tar" to be able to archive. I hope folks will find this as useful as we do here. Do send me any problems or suggestions for improvements (you can already see the beginnings of one or two, but I didn't want to break it before sending it out today). ==============cut here============== #!/usr/bin/perl # # $Id: mkshadowdir.pl,v 1.9 90/01/03 14:46:46 hakanson Exp $ # # Make a shadow directory of symlinks to a directory tree. # Marion Hakanson (hakanson@cse.ogi.edu) # Oregon Graduate Institute of Science and Technology $prog = $0; $prog =~ s?.*/??; $FALSE = 0; $TRUE = 1; # Defaults # for -e option when we add it (put these in a file?) # Note the need for escaping things for the shell, # and putting blanks between the elements. $exclude = " ! \\( -type d -name RCS -prune \\)"; $exclude .= " ! \\( -type f \\( -name Make.log -o -name Make.err \\) \\)"; $preserve = $FALSE; # for -p option when we add it (preserve dir. modes) $quiet = $FALSE; # for -q option when we add it $shadroot = 'SRC'; # for -r option when we add it $verbose = $FALSE; # for -v option when we add it unless ( $#ARGV == $[ + 1 ) { print STDERR "usage: $prog real-path shadow-path\n"; exit(1); } $real = shift; $shad = shift; chop($cwd = `pwd`); # save for below mkdir($shad,0777) || die "Can't mkdir $shad: $!, aborted"; chdir($shad) || die "Can't chdir $shad: $!, aborted"; chop($shad = `pwd`); chdir($cwd) || die "Can't chdir back to $cwd: $!, aborted"; chdir($real) || die "Can't chdir $real: $!, aborted"; chop($real_abs = `pwd`); unless ( $real =~ m?^/.*? ) { print STDERR "$prog: $real not absolute path, using $real_abs\n" unless ( $quiet ); $real = $real_abs; } open(FIND, "find . $exclude -print |") || die "Can't run 'find' command, aborted"; # skip the first "." entry chop($_ = <FIND>); m?^\.$? || die "'find' command's first output not '.', aborted"; symlink("$real", "$shad/$shadroot") || die "Can't symlink $shad/$shadroot: $!, aborted"; print "$real\n" unless ( $quiet ); while ( <FIND> ) { chop; # clean up for appending, plus a sanity check s?^\./?? || die "Unexpected output from 'find' command: $_, aborted"; $tail = $_; $tail =~ s?^.*/??; die "$shadroot occurs in $real, aborted" if ( $tail eq $shadroot ); if ( -l ) { defined ( $sym = readlink("$real/$_") ) || die "Can't readlink $real/$_: $!, aborted"; symlink($sym, "$shad/$_") || die "Can't symlink $shad/$_: $!, aborted"; print "$real/$_ -> $sym\n" if ( $verbose ); next; } if ( -d _ ) { # try to avoid a major loop-type bummer die "$shad is a subdirectory of $real, aborted" if ( "$real_abs/$_" eq $shad ); mkdir("$shad/$_", 0777) || die "Can't mkdir $shad/$_: $!, aborted"; symlink("../$shadroot/$tail", "$shad/$_/$shadroot") || die "Can't symlink $shad/$_/$shadroot: $!, aborted"; print "$real/$_\n" unless ( $quiet ); next; } symlink("$shadroot/$tail", "$shad/$_") || die "Can't symlink $shad/$_: $!, aborted"; print "$real/$_\n" if ( $verbose ); } close(FIND); exit($?); ==============cut here============== -- Marion Hakanson Domain: hakanson@cse.ogi.edu UUCP : {hp-pcd,tektronix}!ogicse!hakanson