zsh-users
 help / color / mirror / code / Atom feed
* Setting paths with ~'s in values.
@ 1999-02-12 20:17 Larry P . Schrof
  1999-02-12 22:05 ` Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Larry P . Schrof @ 1999-02-12 20:17 UTC (permalink / raw)
  To: zsh-users

I have many different machine that I have accouts on, so I conditionally
set my path with the following in my .zshenv ...

---
# Generate a nice-looking path, including only directories that exist.
for t_path in "${(f)$(<${HOME}/.zpaths)}"
do
    if 
        [[ -d $t_path ]]
    then 
        PATH=${PATH}:${~t_path}
    fi
done

PATH=${PATH[2,-1]}	# Nuke the leading ':'
---

.zpaths is a file that contains one directory per line.
It starts with the following entries:

~/bin
~/loc/bin
~/loc/X11R6/bin
...

>From the man page, I was under the impression that putting the ~
before the variable would expand the '~' in each of those paths.
Apparently, it does not. I could probably make a variable substituion
from '~' to ${HOME}, but it seems like there should be a more elegant way
to do it. Obiously, I don't want to explicitly enter the full path of
${HOME} in .zpaths.

Suggestions?

Thanks
- Larry


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Setting paths with ~'s in values.
  1999-02-12 20:17 Setting paths with ~'s in values Larry P . Schrof
@ 1999-02-12 22:05 ` Bart Schaefer
  1999-02-12 22:29   ` Bart Schaefer
  1999-02-22 22:20   ` Danny Dulai
  0 siblings, 2 replies; 7+ messages in thread
From: Bart Schaefer @ 1999-02-12 22:05 UTC (permalink / raw)
  To: Larry P . Schrof, zsh-users

On Feb 12,  2:17pm, Larry P . Schrof wrote:
> Subject: Setting paths with ~'s in values.
> ---
> # Generate a nice-looking path, including only directories that exist.
> for t_path in "${(f)$(<${HOME}/.zpaths)}"
> do
>     if 
>         [[ -d $t_path ]]
>     then 
>         PATH=${PATH}:${~t_path}
>     fi
> done
> 
> PATH=${PATH[2,-1]}	# Nuke the leading ':'
> ---
> 
> From the man page, I was under the impression that putting the ~
> before the variable would expand the '~' in each of those paths.

No.  What the ~ in ${~t_path} does is make the filename *generation*
characters in the value "available" to be processed later, when regular
filename generation takes place (see the "Expansion" part of the info
docs, or "man zshexpn").  This doesn't apply to filename *expansion*,
which is the ~ character.  Even if it did, expansion/generation isn't
done on the right-hand-side of scalar parameter assignments.

The preferred solution to this problem is to use the $path array, which
is automatically converted by zsh to a colon-separated string which is
stuffed into the $PATH environment.  Filename generation and expansion
is done in array assignments -- but that still doesn't expand the ~ .
So you need an additional "eval" for that, which means you don't need
the ~ any more.

Also, you don't need to split the .zpaths file by lines with ${(f)...}
unless some of your paths contain spaces (in which case the eval gets
more complicated too).

A direct translation would thus be:

  for t_path in $(<${HOME}/.zpaths)
  do
      if 
          [[ -d $t_path ]]
      then 
          eval path=\( $path $t_path \)
      fi
  done

and you don't need the extra step of removing the leading colon.  But
there's a better, faster, smarter way to do the same thing:

  eval path=\( ${^$(<${HOME}/.zpaths)}'(|)(/)' \)

Here, the ${^...} takes the place of the "for" loop, the (/) tests a
glob pattern to see if it refers to a directory, and the (|) turns each
of the lines from .zpaths into an equivalent glob pattern so that (/)
test is applied.  The quotes and backslashes just make sure that the
globbing and array assignment steps are delayed until the "eval" runs.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Setting paths with ~'s in values.
  1999-02-12 22:05 ` Bart Schaefer
@ 1999-02-12 22:29   ` Bart Schaefer
  1999-02-22 22:20   ` Danny Dulai
  1 sibling, 0 replies; 7+ messages in thread
From: Bart Schaefer @ 1999-02-12 22:29 UTC (permalink / raw)
  To: Larry P . Schrof, zsh-users

On Feb 12,  2:05pm, Bart Schaefer wrote:
> [...]  Filename generation and expansion
> is done in array assignments -- but that still doesn't expand the ~ .
> So you need an additional "eval" for that, which means you don't need
> the ~ any more.

It just occurred to me that this is a potentially confusing paragraph.

The ~ that you don't need if you have an "eval" is the one in ${~t_path}.

The ~ that expands only when you have the "eval" is the one in each line
read from .zpaths.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Setting paths with ~'s in values.
  1999-02-12 22:05 ` Bart Schaefer
  1999-02-12 22:29   ` Bart Schaefer
@ 1999-02-22 22:20   ` Danny Dulai
  1999-02-23  4:58     ` Bart Schaefer
  1 sibling, 1 reply; 7+ messages in thread
From: Danny Dulai @ 1999-02-22 22:20 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

Quoting Bart Schaefer (schaefer@brasslantern.com):
> A direct translation would thus be:
> 
>   for t_path in $(<${HOME}/.zpaths)
>   do
>       if 
>           [[ -d $t_path ]]
>       then 
>           eval path=\( $path $t_path \)
>       fi
>   done

This didnt seem to add the paths with ~ in them because the ~ didnt get
expanded in the test for existence. i had to do an eval before the if, so
the -d would work:

 for t_path in $(<${HOME}/.zpaths)
 do
     eval t_path=$t_path
     if [ -d $t_path ]; then 
         path=( $path $t_path )
     fi
 done

This works perfectly for me.

> and you don't need the extra step of removing the leading colon.  But
> there's a better, faster, smarter way to do the same thing:
> 
>   eval path=\( ${^$(<${HOME}/.zpaths)}'(|)(/)' \)
> 
> Here, the ${^...} takes the place of the "for" loop, the (/) tests a
> glob pattern to see if it refers to a directory, and the (|) turns each
> of the lines from .zpaths into an equivalent glob pattern so that (/)
> test is applied.  The quotes and backslashes just make sure that the
> globbing and array assignment steps are delayed until the "eval" runs.

Aftertmuch of fiddling with this, I found it works if I have NULL_GLOB set.

eval path=\( ${^$(<${HOME}/.zpaths)}'(|)(/N)' \)

works even if you don't have that option st (good for using it in .zshenv
if you set optoin in .zshrc).
-- 
___________________________________________________________________________
Danny Dulai                                           Feet. Pumice. Lotion.
http://www.ishiboo.com/~nirva/                            nirva@ishiboo.com


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Setting paths with ~'s in values.
  1999-02-22 22:20   ` Danny Dulai
@ 1999-02-23  4:58     ` Bart Schaefer
  1999-02-23  8:39       ` Danny Dulai
  0 siblings, 1 reply; 7+ messages in thread
From: Bart Schaefer @ 1999-02-23  4:58 UTC (permalink / raw)
  To: Danny Dulai; +Cc: zsh-users

Danny Dulai writes:
 > Quoting Bart Schaefer (schaefer@brasslantern.com):
 > > 
 > >   for t_path in $(<${HOME}/.zpaths)
 > >   do
 > >       if 
 > >           [[ -d $t_path ]]
 > >       then 
 > >           eval path=\( $path $t_path \)
 > >       fi
 > >   done
 > 
 > This didnt seem to add the paths with ~ in them because the ~ didnt get
 > expanded in the test for existence.

Right, silly me.  There was even some discussion of file expansion (or
more accurately, lack thereof) in [[ ... ]] expressions not long after
this.

 > > and you don't need the extra step of removing the leading colon.  But
 > > there's a better, faster, smarter way to do the same thing:
 > > 
 > >   eval path=\( ${^$(<${HOME}/.zpaths)}'(|)(/)' \)
 > 
 > Aftertmuch of fiddling with this, I found it works if I have NULL_GLOB set.

Didn't I send a follow-up about that?  I thought I had ... using (N/)
is exactly the right thing there.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Setting paths with ~'s in values.
  1999-02-23  4:58     ` Bart Schaefer
@ 1999-02-23  8:39       ` Danny Dulai
  1999-02-24  5:07         ` Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Danny Dulai @ 1999-02-23  8:39 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

Quoting Bart Schaefer (schaefer@tiny.zanshin.com):
> Danny Dulai writes:
>  > Quoting Bart Schaefer (schaefer@brasslantern.com):
>  > > 
>  > >   for t_path in $(<${HOME}/.zpaths)
>  > >   do
>  > >       if 
>  > >           [[ -d $t_path ]]
>  > >       then 
>  > >           eval path=\( $path $t_path \)
>  > >       fi
>  > >   done
>  > 
>  > This didnt seem to add the paths with ~ in them because the ~ didnt get
>  > expanded in the test for existence.
> 
> Right, silly me.  There was even some discussion of file expansion (or
> more accurately, lack thereof) in [[ ... ]] expressions not long after
> this.

what is the difference between [[ ... ]] and [ ... ] ?

Is [[ the builtin version of the test command? Some systems I've seen have
has the [ command as a symlink to test. but zsh seems to have [ as a
builtin. So what is the diff between [[ ... ]] and [ ... ] ?

-- 
___________________________________________________________________________
Danny Dulai                                           Feet. Pumice. Lotion.
http://www.ishiboo.com/~nirva/                            nirva@ishiboo.com


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Setting paths with ~'s in values.
  1999-02-23  8:39       ` Danny Dulai
@ 1999-02-24  5:07         ` Bart Schaefer
  0 siblings, 0 replies; 7+ messages in thread
From: Bart Schaefer @ 1999-02-24  5:07 UTC (permalink / raw)
  To: Danny Dulai; +Cc: Bart Schaefer, zsh-users

Danny Dulai writes:
 > what is the difference between [[ ... ]] and [ ... ] ?

`[[ ... ]]` is a lexical construct; in effect, `[[` and `]]` are
reserved words (though I don't recall if they're actually implemented
that way).  `[` is just a command that happens to look for an argument
']', and interprets everything in between.

That means that the `...` in a `[[ ... ]]` expression can be treated
specially by the parser, so you can use things like `&&` and `||`
where `[` and `test` require -a and -o.  In particular, the equality
test in a `[[`-expression uses pattern matching, so glob characters
in such expressions are not expanded against the filesystem.  That's
what I've repeatedly been forgetting the last few weeks.

 > Is [[ the builtin version of the test command?

No, `[` is the builtin version of `test`; but many of the conditional
expressions supported by `test` are also supported by `[[ ... ]]`,
which is the source of much of this confusion.


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~1999-02-24  5:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-02-12 20:17 Setting paths with ~'s in values Larry P . Schrof
1999-02-12 22:05 ` Bart Schaefer
1999-02-12 22:29   ` Bart Schaefer
1999-02-22 22:20   ` Danny Dulai
1999-02-23  4:58     ` Bart Schaefer
1999-02-23  8:39       ` Danny Dulai
1999-02-24  5:07         ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).