> Norman Ramsey <[EMAIL PROTECTED]> writes:
> > I can always call my script 'darcs', have it do what it understands
> > and then delegate the rest to the next darcs on my $PATH.
>
> Currently all my wrappers are called "twb-foo" because I couldn't work
> out a way to elegantly remove entries from $PATH in POSIX sh. In
> particular, I couldn't handle the case where the wrapper was not from
> the first dir in $PATH.
>
> I assume you've found a way to do this robustly, since from your
> sentiment I doubt anything else would be acceptable to you.
Oh no, I have a double standard---I'm quite willing to write crappy
code for myself, as long as nobody ever sees it. But you've been
quite polite with all my ranting, and I do believe this code is
robust, although I'm not sure I tested it on anything three deep since
after the day it was written.
> Would you care to share your code?
Here is a really hideous ksh script called 'nextbinary'.
Your shell script does its thing and then something like
exec `nextbinary $0` arguments ...
nextbinary returns the next binary on the $PATH that is not the same
file as the one passed in as a parameter. I had to write samefile.c
to test to see if two files were the same file, since I couldn't find
an easy way to do this from whatever ksh version I was using that
year.
I don't muck with $PATH but rather iterate through its elements
explicitly.
I'm sure a knowledgeable person could translate the ksh to bash.
The samefile.c program is straightforward and not embarrassing.
Norman
#!/bin/ksh
#
# nextbinary fullpathname
#
# searches user's $PATH for next binary after current one
if [ $# -ne 1 ]; then
echo "Usage: $0 pathname" 1>&2; exit 1;
fi
full="$1"
base="`basename $1`"
dir="`dirname $1`"
found=
xxx="$IFS"
IFS=":"
case $dir in
*/*)
for i in $PATH ; do
IFS="$xxx"
if samefile $i/$base $full; then found=1
elif [ -n "$found" -a -x "$i/$base" -a ! -d "$i/$base" ]; then
print $i/$base; exit 0
fi
done
IFS="$xxx"
;;
*)
for i in $PATH ; do
IFS="$xxx"
if [ -z "$found" -a ! -d "$i/$base" ] && samefile "$i/$base" $full;
then
found=1
elif [ -n "$found" -a -x "$i/$base" -a ! -d "$i/$base" ]; then
print $i/$base; exit 0
fi
done
if [ -z "$found" ]; then # didn't find exactly this file on path
# look for first executable file on path
IFS=":"
for i in $PATH ; do
IFS="$xxx"
if [ -z "$found" -a -x "$i/$base" -a ! -d "$i/$base" ]; then
found=1
elif [ -n "$found" -a -x "$i/$base" -a ! -d "$i/$base" ]; then
print $i/$base; exit 0
fi
done
IFS="$xxx"
fi
;;
esac
echo "No $base on" '$PATH' after "$full" 1>&2
exit 1
/* samefile -- succeeds if two files exist and are the same */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
int main (int argc, char *argv[]) {
int i;
struct stat buf1, buf2;
if (argc != 3) {
fprintf(stderr, "Usage: %s file1 file2\n", argv[0]);
exit(2);
}
if (stat(argv[1], &buf1)) exit(1);
if (stat(argv[2], &buf2)) exit(1);
if (buf1.st_dev == buf2.st_dev && buf1.st_ino == buf2.st_ino)
exit(0);
else
exit(1);
}
_______________________________________________
darcs-users mailing list
[email protected]
http://lists.osuosl.org/mailman/listinfo/darcs-users