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