Go Back   The macosxhints Forums > OS X Help Requests > UNIX - General



Reply
 
Thread Tools Rate Thread Display Modes
Old 03-24-2003, 12:32 AM   #1
Titanium Man
Guest
 
Posts: n/a
How to get this to work in zsh?

Hello all, I've been playing with a snippet of code to remove non-existent directories from my path. This incarnation of the incantation is by mervTormel:

pwrangle () # march thru path elements removing non-existent ones
{
local dlist=$PATH
local p=""
local IFS=": "

for x in $dlist;
do
if [ -d $x ] ; then p=$p:$x ; fi
done

export PATH="${HOME}/bin${p}" ;
}


Now, when I do this in bash (having set -xv to see what's going on), $PATH is separated out into individual directories which are then tested (the '-x' part). However, when running 'pwrangle' in zsh, the entire $PATH is tested all at once. What gives?
  Reply With Quote
Old 03-24-2003, 03:09 AM   #2
below
Triple-A Player
 
Join Date: Aug 2002
Location: Germany
Posts: 108
Try using $path instead of $PATH, that should work.

$PATH has the paths seperated by colons, $path is the array of paths.

But it seems that the zshguide even contains an example for what you would like to do (http://zsh.sunsite.dk/Guide/zshguide02.html#l24 )

Thanks to macosxhints for showing me the error of my ways (tcsh)...

Alex
below is offline   Reply With Quote
Old 03-24-2003, 09:33 AM   #3
Titanium Man
Guest
 
Posts: n/a
Thanks for replying, below. It had been a while since I'd looked at that section of the zsh guide. However, what it's talking about is removing duplicates from your path. Actually, I had already included

typeset -U path cdpath manpath fpath

in my .zshenv. What that pwrangle function does is remove directories that don't exist from the path. Also, I'm trying to figure out why bash will strip the colon from $PATH and check each directory, but zsh doesn't. (I guess fundamentla differences between shells.) Using $path does seem to get me closer to what I'm trying to do, but there's still an error about not being able to set the path when I do so. Any other ideas? Thanks.
  Reply With Quote
Old 03-24-2003, 10:34 PM   #4
pmccann
Major Leaguer
 
Join Date: Jan 2002
Location: Adelaide, South Australia
Posts: 470
Here's something that seems to work, but I'll not be vouching for the programming style. (Local versus global variables rah rah). In any case, it might give you some ideas about how to implement it in a neater way. (zsh synchronises $path and $PATH, though as pointed out above, they're different beasts. So you can manipulate either one of them, as in the mish-mash below!)

newpath=();
for dir in $path; do
if [[ -d $dir ]]; then
newpath=( $newpath $dir )
fi
done
export PATH=${(j.:.)newpath}

Cheers,
Paul
pmccann is offline   Reply With Quote
Old 03-24-2003, 11:34 PM   #5
Titanium Man
Guest
 
Posts: n/a
Thanks, pmccann. The double bracket thingy [[ -d $dir]] vs. the original single bracket [ -d $x ] along with using $path in the beginning and $PATH at the end seems to have gotten it. Now off to the manpages to see just what the differences are between [[ ]] and [ ], and also to research that last little bit (j.:.)
  Reply With Quote
Old 03-25-2003, 04:07 AM   #6
below
Triple-A Player
 
Join Date: Aug 2002
Location: Germany
Posts: 108
No need to look:

... tests in sh used a single pair of brackets, ... The Korn shell was deliberately made to be different, and zsh follows that. The reason is that `[[' is treated specially, which allows the shell to do some extra checks and allows more natural syntax. For example, ... in sh it's dangerous to test a parameter which may be empty: `[ $var = foo ]' will fail if $var is empty, because in that case the word is missed out and the shell never knows it was supposed to be there; with `[[ ... ]]', this is quite safe because the shell is aware there's a word before the `=', even if it's empty. Also, you can use `&&' and `||' to mean logical `and' and `or', ... Actually, zsh provides the old form of test for backward compatibility, but things will work a lot more smoothly if you don't use it.
Taken from the zshguide

So the bottom line is: In zsh, use [[..]] for all your testing needs. I forget this often enough...

Alex
below is offline   Reply With Quote
Old 03-25-2003, 05:06 AM   #7
jkp23
Triple-A Player
 
Join Date: Feb 2003
Location: back in t'ol' smoke :(
Posts: 225
Quote:
Originally posted by below
Thanks to macosxhints for showing me the error of my ways (tcsh)...
Alex

so are we saying zsh is a better bet? as someone who is about to go headlong into getting to grips with one or another shell, it would be nice to know what everyone reckons to be 'the best'.
__________________
JKP.
jkp23 is offline   Reply With Quote
Old 03-25-2003, 03:06 PM   #8
below
Triple-A Player
 
Join Date: Aug 2002
Location: Germany
Posts: 108
"we" are indeed saying zsh is the better bet.
zsh IMHO has the best of all worlds, allows you to do more, with less hassle.
There might be a little learning curve involved, but where isn't...

Alex
below is offline   Reply With Quote
Old 03-25-2003, 06:44 PM   #9
thatch
All Star
 
Join Date: Jan 2002
Posts: 534
ditto what below said about zsh. It's the best shell IMHO.
thatch is offline   Reply With Quote
Old 03-25-2003, 10:39 PM   #10
Titanium Man
Guest
 
Posts: n/a
Thanks below, that's some Good Stuff®. jkp23, zsh is a great interactive shell. You can do things like

ls -ld *(/)

to list only directories or

ls **/*.dmg

to recursively find all .dmg files. Now, no one likes a preachy zsh user so I'll say that bash and tcsh are pretty good interactive shells (although they don't have as many bells and whistles as zsh). As far as programming/script writing is concerned, zsh is maybe a bit TOO configurable. You may have to take into account that other users might be using options that would mess up your script, and need to unset those options in your script. I chose zsh over tcsh because it's in the sh family (why learn a csh related shell like tcsh for interactive use and an sh shell for scripting?). I chose zsh over bash because I'm too lazy to do all that typing. (zsh gives you all kinds of command completion).
  Reply With Quote
Old 03-25-2003, 11:09 PM   #11
pmccann
Major Leaguer
 
Join Date: Jan 2002
Location: Adelaide, South Australia
Posts: 470
Ah well, since noone else has popped this bit of info into the discussion...

export PATH=${(j.:.)newpath}

just joins ("j") the newpath array using the ":" string in order to return a nice scalar (as required for PATH). Very cute.

Cheers,
Paul (who likes threads to be self-contained so that when the same thing comes up again I won't have to be scratching my spartan noggin about the j.:. thing for too long)
pmccann is offline   Reply With Quote
Old 03-26-2003, 09:07 AM   #12
Titanium Man
Guest
 
Posts: n/a
Thanks Paul!
  Reply With Quote
Old 03-26-2003, 09:55 AM   #13
MasterUltan
Prospect
 
Join Date: Sep 2002
Posts: 4
IFS expansion in zsh

In zsh, IFS expansion doesn't occur unless you have set the SH_WORD_SPLIT option. Alternatively, you could use ${=PATH} to cause IFS expansion for the variable PATH but leave the shell environment alone.

example:

$a=w:x:y:z
$cat $a
cat: w:x:y:z: No such file or directory
$cat ${=a}
cat: w: No such file or directory
cat: x: No such file or directory
cat: y: No such file or directory
cat: z: No such file or directory
MasterUltan is offline   Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



All times are GMT -5. The time now is 06:11 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.