Path: utzoo!utgpu!cs.utexas.edu!convex!news From: tchrist@convex.COM (Tom Christiansen) Newsgroups: alt.sources.d Subject: Re: Multiple executables in path (Was: NON-SOURCE POSTINGS CONSIDERED HARMFUL!) Message-ID: <1991Jan21.171227.12138@convex.com> Date: 21 Jan 91 17:12:27 GMT References: <26327:Jan2023:24:4091@kramden.acf.nyu.edu> <1991Jan21.082717.22130@convex.com> <305:Jan2114:26:5191@kramden.acf.nyu.edu> Sender: news@convex.com (news access account) Reply-To: tchrist@convex.COM (Tom Christiansen) Organization: CONVEX Software Development, Richardson, TX Lines: 130 Nntp-Posting-Host: pixel.convex.com From the keyboard of brnstnd@kramden.acf.nyu.edu (Dan Bernstein): :In article <1991Jan21.082717.22130@convex.com> tchrist@convex.COM (Tom Christiansen) writes: :> The quotes you needed for your solution were gross and nigh :> unto illegible. : :Illegible? It's not my fault if you haven't written enough shell code to :instantly recognize '\''. Or would you prefer double quoting? There's our Dan, who when he cannot win his point on technical merits, resorts instead to petty, unfounded (and flat-out wrong), ad hominem attacks laced with deprecating sarcasm in order to belittle the other party. Why does it make you feel better to insult other people, Dan? Is it because you think so little of yourself you have to put everybody else down? If that's your game, why don't you go off to Fidonet or some other even more puerile bulletin board system where this behavior may be more expected? Better yet, go see a good counselor. Maybe you wouldn't be posting so much drivel if you hadn't been kicked out of Princeton. Would you care to tell us all about that incident, Dan? And while you're at it, it would be interesting to learn what is wrong inside of you that makes you want to convert every newsgroup you touch into a battleground for petulant, anal-retentive abuse? What ever did happen to rec.games.rpg anyway? : echo `echo "$PATH" | tr : '\012' | sed -e 's+$+/!:1+' -e 's:^:/.[.]:'` : | sed 's:/../:/:g' :It's just not as instantly obvious as the pipeline. I prefer easily :maintainable code with obvious data flaw (and obvious firewalls) to an :unportable, unconventional, ungodly muck. Data flaw? There you have it. Unportable: I think not. In fact, perl runs on more machines than sed and tr. I've not seen DOS or Macintosh ports of them, let alone of the shell-from-hell you like to post things in. Unconventional: That's what the Fortran programmer said when he first saw Algol, Pascal, C, etc. Or if you prefer, the MVS hack when he saw UNIX. As you can seen, this argument merely demonstrates a myopic approach to new and better technology. Ungodly: Oh, now *there's* an effective criticism for you. I'm sure the whole net will rise up in popular accord for this one. With gods on your side, who can stand against you? Anything that requires multiple levels of evaluation is more complex than something that does not. You are looking at the problem from a "munge the I/O stream until done" approach, which is often just a crufty hack for inadequate tools. Let's sit back and look at the algorithm. What is really desired here? It's really much simpler than you've made it out to be. All that's needed is to check each component in the user's path for an executable of that name, and if it exists, print out the full pathname. That's surely not an algorithm that's conveyed by your solution, but that's all that's needed here. Here's my solution: $file = shift; for $dir (split(/:/,$ENV{"PATH"})) { print "$path\n" if -x ($path="$dir/$file"); } I've not gone to much trouble to obfuscate it, like using && notation: -x ($path="$dir/$file") && print "$path\n"; or some greply convolution. If you want it unraveled a bit because you prefer assignments to stand on their own and not be used in expressions, you could have this: $file = shift; for $dir (split(/:/,$ENV{"PATH"})) { $path = "$dir/$file"; if (-x $path) { print "$path\n"; } } Notice how easily I can deal with multiple arguments by simply slapping another for loop around everything: for $file (@ARGV) { for $dir (split(/:/,$ENV{"PATH"})) { print "$path\n" if -x ($path="$dir/$file"); } } Notice how little confusion is added by adding that functionality. That's not easily done in csh. I'd like to see others' opinions on algorithmic complexity here. Which way is more straightforward? Bear in mind that Dan's solution, here reproduced for your inspection: alias which 'echo `echo "$PATH" | tr : '\''\012'\'' | sed -e '\''s+$+/\!:1+'\'' -e '\''s:^:/.[.]:'\''` | sed '\''s:/../:/:g'\''' contains 30 quotes, 9 backslashes, and several levels of evaluation to worry about. Of course, in a real shell instead of the abomination cited above, most of these problems go away: function mwhence { for file in $*; do for dir in `echo $PATH | tr ':' ' '`; do path=$dir/$file if [ -x $path ]; then echo $path; fi # AKA: test -x $path && echo $path done done } For the truly curious, the ksh solution takes 2x time time the perl one does, probably because of having to call tr. If I had used the ## or %% variable munging, I probably could have trimmed this down, but that's not as succinctly expressed and I didn't feel like playing with it. It's a good deal faster than the disgusting csh alias. We'll see who has to say what here about the shell and the perl algorithm (which are equivalent) versus the massively piped one. Of course, a lot of the UNIX gurus are here in Dallas right now for USENIX, plus a lot more have given up on the alt hierarchy, and a few have given up on anything that should really have been posted to alt.flame.dan-bernstein instead. --tom -- "Hey, did you hear Stallman has replaced /vmunix with /vmunix.el? Now he can finally have the whole O/S built-in to his editor like he always wanted!" --me (Tom Christiansen )