zsh-users
 help / color / mirror / code / Atom feed
* Re: Running "unset path" breaks PATH despite emulation being enabled
       [not found] ` <CAHYJk3RD6p7PwRaZSUbJSAE0Bi6_2+NKLC3MV+32Lh+PmzsAdA@mail.gmail.com>
@ 2017-09-09 21:38   ` Eric Pruitt
  2017-09-09 22:25     ` Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Eric Pruitt @ 2017-09-09 21:38 UTC (permalink / raw)
  To: zsh-users

I'm moving this discussion from zsh-workers to zsh-users since it's been
established that the behavior I observed isn't necessarily a bug.

On Fri, Sep 08, 2017 at 01:30:05PM +0200, Mikael Magnusson wrote:
> This works fine if you start zsh as sh though, ie either make a
> symlink ln -s =zsh sh; ./sh or do ARGV0=sh zsh
> It can't really work in the 'emulate sh' case since the parameter
> $path is then already created and it would be quite controversial for
> emulate to remove parameters from the shell environment.

What I ended up doing is adding this to the top of my script:

    test "${ZSH_NAME:-sh}" = "sh" || exec -a sh zsh "$0" "$@"

I would like to replace "zsh" with the absolute path of the Z shell
interpreter in case the "zsh" being executed is not the first one listed
in a $PATH folder. After reading through some documentation and
reviewing the output of "set", I don't see a way to do this. For
comparison, Bash sets $BASH to the interpreter's path:

    ~$ echo $BASH
    /home/ericpruitt/.local/bin/bash

Is there a similar value in Z shell or a built-in I can use?

Thanks,
Eric


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

* Re: Running "unset path" breaks PATH despite emulation being enabled
  2017-09-09 21:38   ` Running "unset path" breaks PATH despite emulation being enabled Eric Pruitt
@ 2017-09-09 22:25     ` Bart Schaefer
  2017-09-09 22:38       ` Eric Pruitt
  2017-09-10 18:51       ` Chet Ramey
  0 siblings, 2 replies; 7+ messages in thread
From: Bart Schaefer @ 2017-09-09 22:25 UTC (permalink / raw)
  To: zsh-users

On Sep 9,  2:38pm, Eric Pruitt wrote:
} Subject: Re: Running "unset path" breaks PATH despite emulation being enab
}
} I would like to replace "zsh" with the absolute path of the Z shell
} interpreter in case the "zsh" being executed is not the first one listed
} in a $PATH folder. After reading through some documentation and
} reviewing the output of "set", I don't see a way to do this. For
} comparison, Bash sets $BASH to the interpreter's path:

I just had a look at the Bash sources.  Chet will correct me if I'm wrong,
but as far as I can tell if argv[0] is not already at least a partial
path, then $BASH is set by doing a path search for the first matching
executable.  Thus $BASH will be "the first one listed in a $PATH folder" 
when argv[0] contains no "/" separators, even if the actual executable
came from somewhere else.

} Is there a similar value in Z shell or a built-in I can use?

$ZSH_ARGZERO in sufficiently recent versions of the shell will give you
the equivalent information, you just have to do the path search part
yourself, which is simple enough with the "=" expander:

[[ =$ZSH_ARGZERO != =$ZSH_NAME ]] && ...

If NO_EQUALS is set then some uses of `whence ...` might be needed.


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

* Re: Running "unset path" breaks PATH despite emulation being enabled
  2017-09-09 22:25     ` Bart Schaefer
@ 2017-09-09 22:38       ` Eric Pruitt
  2017-09-10  9:42         ` Daniel Shahaf
  2017-09-10 23:50         ` Bart Schaefer
  2017-09-10 18:51       ` Chet Ramey
  1 sibling, 2 replies; 7+ messages in thread
From: Eric Pruitt @ 2017-09-09 22:38 UTC (permalink / raw)
  To: zsh-users

On Sat, Sep 09, 2017 at 03:25:12PM -0700, Bart Schaefer wrote:
> > Is there a similar value in Z shell or a built-in I can use?
>
> $ZSH_ARGZERO in sufficiently recent versions of the shell will give you
> the equivalent information, you just have to do the path search part
> yourself

This does not seem to be the case:

    playground$ cp $(which bash) $(which zsh) .
    '/home/ericpruitt/.local/bin/bash' -> './bash'
    '/usr/bin/zsh' -> './zsh'
    playground$ (PATH=/ ./bash -c 'echo $BASH')
    /tmp/tmp.FsPM5kO6Sn/playground/bash
    playground$ (PATH=/ ./zsh -c 'echo =$ZSH_NAME')
    zsh:1: zsh not found

I'm not sure if I misunderstood or didn't clearly explain what I wanted.
What want is for Z shell to return is the name to the invoked
interpreter which is what $BASH shows even when $PATH doesn't contain
Bash.

Eric


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

* Re: Running "unset path" breaks PATH despite emulation being enabled
  2017-09-09 22:38       ` Eric Pruitt
@ 2017-09-10  9:42         ` Daniel Shahaf
  2017-09-10 23:50         ` Bart Schaefer
  1 sibling, 0 replies; 7+ messages in thread
From: Daniel Shahaf @ 2017-09-10  9:42 UTC (permalink / raw)
  To: zsh-users

Eric Pruitt wrote on Sat, 09 Sep 2017 15:38 -0700:
> I'm not sure if I misunderstood or didn't clearly explain what I wanted.
> What want is for Z shell to return is the name to the invoked
> interpreter

You can use /proc/$$/exe if your system has it, but there's no
portable solution.  In syscall terms, execve() doesn't pass the first
parameter to the child, only the argv array, which can lie about the
command's name.


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

* Re: Running "unset path" breaks PATH despite emulation being enabled
  2017-09-09 22:25     ` Bart Schaefer
  2017-09-09 22:38       ` Eric Pruitt
@ 2017-09-10 18:51       ` Chet Ramey
  1 sibling, 0 replies; 7+ messages in thread
From: Chet Ramey @ 2017-09-10 18:51 UTC (permalink / raw)
  To: Bart Schaefer, zsh-users; +Cc: chet.ramey

On 9/9/17 6:25 PM, Bart Schaefer wrote:

> I just had a look at the Bash sources.  Chet will correct me if I'm wrong,
> but as far as I can tell if argv[0] is not already at least a partial
> path, then $BASH is set by doing a path search for the first matching
> executable.  Thus $BASH will be "the first one listed in a $PATH folder" 
> when argv[0] contains no "/" separators, even if the actual executable
> came from somewhere else.

This is about the best you can do. The only additional thing would be to
assume that the executed binary came from the current directory if you
can't find it in $PATH, because that's how execve(2) and its siblings work.
It's a heuristic based on how the shell is commonly executed, but it can
certainly be fooled.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
		 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://cnswww.cns.cwru.edu/~chet/


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

* Re: Running "unset path" breaks PATH despite emulation being enabled
  2017-09-09 22:38       ` Eric Pruitt
  2017-09-10  9:42         ` Daniel Shahaf
@ 2017-09-10 23:50         ` Bart Schaefer
  2017-09-11  4:39           ` Eric Pruitt
  1 sibling, 1 reply; 7+ messages in thread
From: Bart Schaefer @ 2017-09-10 23:50 UTC (permalink / raw)
  To: zsh-users

On Sep 9,  3:38pm, Eric Pruitt wrote:
}
} What want is for Z shell to return is the name to the invoked
} interpreter which is what $BASH shows even when $PATH doesn't contain
} Bash.

OK, that's just a little bit trickier.  Here's script equivalent of the 
actual heuristic Bash uses:

  # Set $ZSH the way Bash sets $BASH
  get_ZSH() {
    emulate -L zsh
    if [[ -o login && $ZSH_ARGZERO != /* ]]
    then ZSH=$SHELL
    elif [[ $ZSH_ARGZERO = /* ]]
    then ZSH=$ZSH_ARGZERO
    elif [[ $ZSH_ARGZERO = ./* ]]
    then ZSH=$ZSH_ARGZERO:P
    else
      local -a tname=( $^path/$ZSH_ARGZERO(N[1]) )
      if [[ -z $tname ]]
      then
        if [[ -x $ZSH_ARGZERO ]]
        then ZSH=$ZSH_ARGZERO:P
        else ZSH=$SHELL
        fi
      else
        ZSH=$tname:P
      fi
    fi
  }

This only works if it's executed before any chdir has been done.

For older zsh that don't have the :P modifier, use :A.


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

* Re: Running "unset path" breaks PATH despite emulation being enabled
  2017-09-10 23:50         ` Bart Schaefer
@ 2017-09-11  4:39           ` Eric Pruitt
  0 siblings, 0 replies; 7+ messages in thread
From: Eric Pruitt @ 2017-09-11  4:39 UTC (permalink / raw)
  To: zsh-users

On Sun, Sep 10, 2017 at 04:50:57PM -0700, Bart Schaefer wrote:
> On Sep 9,  3:38pm, Eric Pruitt wrote:
> > What want is for Z shell to return is the name to the invoked
> > interpreter which is what $BASH shows even when $PATH doesn't contain
> > Bash.
>
> OK, that's just a little bit trickier.  Here's script equivalent of the
> actual heuristic Bash uses:
>
>   # Set $ZSH the way Bash sets $BASH
>   [...]
>
> This only works if it's executed before any chdir has been done.
>
> For older zsh that don't have the :P modifier, use :A.

Thanks for taking the time to write out that logic. I use Bash almost
exclusively, and it's been interesting seeing how things are done in Z
shell. In the end I settled for this since the script only needs to
support Linux:

    test "${ZSH_NAME:-sh}" = "sh" || exec -a sh /proc/self/exe "$0" "$@"

Of the four shells I'm supporting for the script in question, Z shell is
the only that deviates from POSIX so much that that it requires special
consideration, and I didn't want to add more than a line or two of logic
for it.

Eric


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

end of thread, other threads:[~2017-09-11  4:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20170908082917.v5j4vczoq75vs5lk@sinister.lan.codevat.com>
     [not found] ` <CAHYJk3RD6p7PwRaZSUbJSAE0Bi6_2+NKLC3MV+32Lh+PmzsAdA@mail.gmail.com>
2017-09-09 21:38   ` Running "unset path" breaks PATH despite emulation being enabled Eric Pruitt
2017-09-09 22:25     ` Bart Schaefer
2017-09-09 22:38       ` Eric Pruitt
2017-09-10  9:42         ` Daniel Shahaf
2017-09-10 23:50         ` Bart Schaefer
2017-09-11  4:39           ` Eric Pruitt
2017-09-10 18:51       ` Chet Ramey

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).