zsh-users
 help / color / mirror / code / Atom feed
* how to refer to basename of $0
@ 2011-07-28 22:55 TJ Luoma
  2011-07-28 23:54 ` Tomasz Moskal
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: TJ Luoma @ 2011-07-28 22:55 UTC (permalink / raw)
  To: Zsh Users

I am trying to move a bunch of my scripts to zsh instead of bash
because I'm starting to run into little differences in the way things
are handled which are annoying, and I figured it made more sense to
just learn one way rather than two.

I have a ".source" file that I use to setup some functions and
variables for use in my scripts, and one of the things it does it
this:

NAME=`basename $0`

which, in bash, gives me the basename of the script. For example, if
the script "foo.sh" read .source like this:

	. $HOME/.source

and then I did

	echo "$NAME"

it would give me

	foo.sh

but in zsh I get

	zsh

Is there a way for me to get the equivalent of `basename $0` when
writing shell scripts in zsh?

(I hope this is understandable. If not, please let me know and I'll
try to rephrase.)

thanks for your time

TjL


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

* Re: how to refer to basename of $0
  2011-07-28 22:55 how to refer to basename of $0 TJ Luoma
@ 2011-07-28 23:54 ` Tomasz Moskal
  2011-07-29  0:24 ` Phil Pennock
  2011-07-29  0:44 ` Benjamin R. Haskell
  2 siblings, 0 replies; 14+ messages in thread
From: Tomasz Moskal @ 2011-07-28 23:54 UTC (permalink / raw)
  To: zsh-users

On Thu, 2011-07-28 at 18:55 -0400, TJ Luoma wrote:
> I have a ".source" file that I use to setup some functions and
> variables for use in my scripts, and one of the things it does it
> this:
> 
> NAME=`basename $0`
> 

name="`basename $0`"
echo $name


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

* Re: how to refer to basename of $0
  2011-07-28 22:55 how to refer to basename of $0 TJ Luoma
  2011-07-28 23:54 ` Tomasz Moskal
@ 2011-07-29  0:24 ` Phil Pennock
  2011-07-29  1:30   ` Tomasz Moskal
  2011-07-29  0:44 ` Benjamin R. Haskell
  2 siblings, 1 reply; 14+ messages in thread
From: Phil Pennock @ 2011-07-29  0:24 UTC (permalink / raw)
  To: TJ Luoma; +Cc: Zsh Users

On 2011-07-28 at 18:55 -0400, TJ Luoma wrote:
> the script "foo.sh" read .source like this:
> 
> 	. $HOME/.source
> 
> and then I did
> 
> 	echo "$NAME"
> 
> it would give me
> 
> 	foo.sh
> 
> but in zsh I get
> 
> 	zsh

Are you sure?

% cat -v foo
. $HOME/bar
% cat -v bar
echo $0
% zsh -f foo
/home/me/bar
% bash foo
foo

The point is that in bash, sourcing a script does not change $0 while in
zsh it does by default, because FUNCTION_ARGZERO is set.

% cat -v foo2
unsetopt function_argzero
. $HOME/bar
% zsh -f foo2
foo2

If you want to be portable to both bash and zsh, then:

  [[ -n $ZSH_VERSION ]] && unsetopt function_argzero

This does, unfortunately, have to be done in the script which does the
including, so you can't have a common library used by both shells which
assumes that $0 is the name of the original file and which can just be
simply included.

-Phil


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

* Re: how to refer to basename of $0
  2011-07-28 22:55 how to refer to basename of $0 TJ Luoma
  2011-07-28 23:54 ` Tomasz Moskal
  2011-07-29  0:24 ` Phil Pennock
@ 2011-07-29  0:44 ` Benjamin R. Haskell
  2011-07-29  1:39   ` TJ Luoma
  2011-07-29  3:05   ` TJ Luoma
  2 siblings, 2 replies; 14+ messages in thread
From: Benjamin R. Haskell @ 2011-07-29  0:44 UTC (permalink / raw)
  To: TJ Luoma; +Cc: Zsh Users

On Thu, 28 Jul 2011, TJ Luoma wrote:

> I am trying to move a bunch of my scripts to zsh instead of bash 
> because I'm starting to run into little differences in the way things 
> are handled which are annoying, and I figured it made more sense to 
> just learn one way rather than two.
>
> I have a ".source" file that I use to setup some functions and 
> variables for use in my scripts, and one of the things it does it 
> this:
>
> NAME=`basename $0`
>
> which, in bash, gives me the basename of the script. For example, if 
> the script "foo.sh" read .source like this:
>
> 	. $HOME/.source
>
> and then I did
>
> 	echo "$NAME"
>
> it would give me
>
> 	foo.sh
>
> but in zsh I get
>
> 	zsh

Sounds like you're not actually 'source'-ing the script.  $0 should give 
you the script name in that case.  $0 will vary if it's in the top-level 
scope or inside a function, though.  For finer-grained control, you can 
use the '(%)' parameter expansion flag on the string "%x".  (also see 
%N, but that has the same caveats as $0, AFAIK.)

Try the script below, running in these several ways:

. ./basename-0.zsh
./basename-0.zsh
eval "$(<basename-0.zsh)"

-- 
Best,
Ben

$ cat > basename-0.zsh <<'SCRIPT'
#!/bin/zsh

echo 0 outside: $0:t
afunction () { echo 0 in afunction: $0:t }
afunction
() { echo 0 in anon: $0:t }
echo 0 in a subshell: "$(/bin/echo $0:t)"

echo %x outside: ${${(%):-%x}:t}
anotherfunc () { echo %x in anotherfunc: ${${(%):-%x}:t} }
anotherfunc
() { echo %x in anon: ${${(%):-%x}:t} }
echo %x in a subshell: "$(/bin/echo ${${(%):-%x}:t})"
SCRIPT
$ chmod +x basename-0.zsh


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

* Re: how to refer to basename of $0
  2011-07-29  0:24 ` Phil Pennock
@ 2011-07-29  1:30   ` Tomasz Moskal
  0 siblings, 0 replies; 14+ messages in thread
From: Tomasz Moskal @ 2011-07-29  1:30 UTC (permalink / raw)
  To: zsh-users



On Thu, 2011-07-28 at 20:24 -0400, Phil Pennock wrote:
> On 2011-07-28 at 18:55 -0400, TJ Luoma wrote:
> > the script "foo.sh" read .source like this:
> > 
> > 	. $HOME/.source
> > 
> > and then I did
> > 
> > 	echo "$NAME"
> > 
> > it would give me
> > 
> > 	foo.sh
> > 
> > but in zsh I get
> > 
> > 	zsh
> 
> Are you sure?
> 
> % cat -v foo
> . $HOME/bar
> % cat -v bar
> echo $0
> % zsh -f foo
> /home/me/bar
> % bash foo
> foo
> 
> The point is that in bash, sourcing a script does not change $0 while in
> zsh it does by default, because FUNCTION_ARGZERO is set.
> 
> % cat -v foo2
> unsetopt function_argzero
> . $HOME/bar
> % zsh -f foo2
> foo2
> 
> If you want to be portable to both bash and zsh, then:
> 
>   [[ -n $ZSH_VERSION ]] && unsetopt function_argzero
> 
> This does, unfortunately, have to be done in the script which does the
> including, so you can't have a common library used by both shells which
> assumes that $0 is the name of the original file and which can just be
> simply included.
> 
> -Phil

Damn, I was too late :-)


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

* Re: how to refer to basename of $0
  2011-07-29  0:44 ` Benjamin R. Haskell
@ 2011-07-29  1:39   ` TJ Luoma
  2011-07-29  2:06     ` Tomasz Moskal
  2011-07-29  4:04     ` Bart Schaefer
  2011-07-29  3:05   ` TJ Luoma
  1 sibling, 2 replies; 14+ messages in thread
From: TJ Luoma @ 2011-07-29  1:39 UTC (permalink / raw)
  To: Zsh Users

Sorry folks, I'm explaining this really badly. Forget I said anything
about bash. I don't care about bash. I'm trying to leave bash behind.

Let me start over. Here's what happens in zsh 4.3.11

# my comments are offset with #
# fyi - "Air%" is my prompt

# just to show that $NAME is empty
	Air% echo $NAME
	Air%


# /tmp/.source has only one line:
	Air% cat /tmp/.source
	NAME=`basename $0`

# here is my 'test.zsh' script:
	Air% cat ./test.zsh
	#!/bin/zsh

	. /tmp/.source

	echo "$NAME"

  	exit 0

# So now I run 'test.zsh' :

	Air% ./test.zsh
	.source

# OK, so you can see that it output '.source' when I wanted it to
output 'test.zsh'

# Next: rename /tmp/.source to ~/.zshenv

	Air% mv /tmp/.source ~/.zshenv

# Edited 'test.zsh'  is now this:

	Air% cat =test.zsh
	#!/bin/zsh

	echo "$NAME"

	exit 0
	#EOF

# now when I run 'test.zsh' again:

	Air% test.zsh
	zsh

# Someone suggested "unsetopt function_argzero" so I added that to .zshenv:

	Air% cat ~/.zshenv
	unsetopt function_argzero

	NAME=`basename $0`

# and re-ran test.zsh, which gave me:

	zsh


Is it even possible to set NAME in .zsh* (and have it return
'test.zsh' or are they called too early in the process?

TjL


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

* Re: how to refer to basename of $0
  2011-07-29  1:39   ` TJ Luoma
@ 2011-07-29  2:06     ` Tomasz Moskal
  2011-07-29  4:04     ` Bart Schaefer
  1 sibling, 0 replies; 14+ messages in thread
From: Tomasz Moskal @ 2011-07-29  2:06 UTC (permalink / raw)
  To: zsh-users



On Thu, 2011-07-28 at 21:39 -0400, TJ Luoma wrote:
> Sorry folks, I'm explaining this really badly. Forget I said anything
> about bash. I don't care about bash. I'm trying to leave bash behind.
> 
> Let me start over. Here's what happens in zsh 4.3.11
> 
> # my comments are offset with #
> # fyi - "Air%" is my prompt
> 
> # just to show that $NAME is empty
> 	Air% echo $NAME
> 	Air%
> 
> 
> # /tmp/.source has only one line:
> 	Air% cat /tmp/.source
> 	NAME=`basename $0`
> 
> # here is my 'test.zsh' script:
> 	Air% cat ./test.zsh
> 	#!/bin/zsh
> 
> 	. /tmp/.source
> 
> 	echo "$NAME"
> 
>   	exit 0
> 
> # So now I run 'test.zsh' :
> 
> 	Air% ./test.zsh
> 	.source
> 
> # OK, so you can see that it output '.source' when I wanted it to
> output 'test.zsh'
> 
> # Next: rename /tmp/.source to ~/.zshenv
> 
> 	Air% mv /tmp/.source ~/.zshenv
> 
> # Edited 'test.zsh'  is now this:
> 
> 	Air% cat =test.zsh
> 	#!/bin/zsh
> 
> 	echo "$NAME"
> 
> 	exit 0
> 	#EOF
> 
> # now when I run 'test.zsh' again:
> 
> 	Air% test.zsh
> 	zsh
> 
> # Someone suggested "unsetopt function_argzero" so I added that to .zshenv:
> 
> 	Air% cat ~/.zshenv
> 	unsetopt function_argzero
> 
> 	NAME=`basename $0`
> 
> # and re-ran test.zsh, which gave me:
> 
> 	zsh
> 
> 
> Is it even possible to set NAME in .zsh* (and have it return
> 'test.zsh' or are they called too early in the process?
> 
> TjL

It's working here:

% cat .zshenv
unsetopt function_argzero
name=`basename $0`

% cat foo
#!/bin/zsh
. ~/.zshenv
echo $name
exit 0

% ./foo
foo

A bit perplexed, this is what I am... Have a look at this:

% zsh -f
% ./foo
foo


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

* Re: how to refer to basename of $0
  2011-07-29  0:44 ` Benjamin R. Haskell
  2011-07-29  1:39   ` TJ Luoma
@ 2011-07-29  3:05   ` TJ Luoma
  1 sibling, 0 replies; 14+ messages in thread
From: TJ Luoma @ 2011-07-29  3:05 UTC (permalink / raw)
  To: Zsh Users

On Thu, Jul 28, 2011 at 8:44 PM, Benjamin R. Haskell <zsh@benizi.com> wrote:
> Sounds like you're not actually 'source'-ing the script.  $0 should give you
> the script name in that case.  $0 will vary if it's in the top-level scope
> or inside a function, though.  For finer-grained control, you can use the
> '(%)' parameter expansion flag on the string "%x".  (also see %N, but that
> has the same caveats as $0, AFAIK.)
>
> Try the script below, running in these several ways:
>
> . ./basename-0.zsh
> ./basename-0.zsh
> eval "$(<basename-0.zsh)"
>
> --
> Best,
> Ben
>
> $ cat > basename-0.zsh <<'SCRIPT'
> #!/bin/zsh
>
> echo 0 outside: $0:t
> afunction () { echo 0 in afunction: $0:t }
> afunction
> () { echo 0 in anon: $0:t }
> echo 0 in a subshell: "$(/bin/echo $0:t)"
>
> echo %x outside: ${${(%):-%x}:t}
> anotherfunc () { echo %x in anotherfunc: ${${(%):-%x}:t} }
> anotherfunc
> () { echo %x in anon: ${${(%):-%x}:t} }
> echo %x in a subshell: "$(/bin/echo ${${(%):-%x}:t})"
> SCRIPT
> $ chmod +x basename-0.zsh

I missed the bottom of this email originally… but "$0:t" seems to be
working just fine, and that's exactly the sort of thing I figured Zsh
must have ;-)


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

* Re: how to refer to basename of $0
  2011-07-29  1:39   ` TJ Luoma
  2011-07-29  2:06     ` Tomasz Moskal
@ 2011-07-29  4:04     ` Bart Schaefer
  2011-07-29  4:50       ` TJ Luoma
  2011-07-29 11:48       ` Tomasz Moskal
  1 sibling, 2 replies; 14+ messages in thread
From: Bart Schaefer @ 2011-07-29  4:04 UTC (permalink / raw)
  To: Zsh Users

On Jul 28,  9:39pm, TJ Luoma wrote:
}
} Is it even possible to set NAME in .zsh* (and have it return
} 'test.zsh' or are they called too early in the process?

This is sounding awfully familiar.  Oh, it was on zsh-workers, where
some of the -users crowd would not have seen it.

Starts here:

http://www.zsh.org/mla/workers/2011/msg00159.html

Interesting branch begins here:

http://www.zsh.org/mla/workers/2011/msg00163.html

Particularly:

http://www.zsh.org/mla/workers//2011/msg00172.html


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

* Re: how to refer to basename of $0
  2011-07-29  4:04     ` Bart Schaefer
@ 2011-07-29  4:50       ` TJ Luoma
  2011-07-29 11:48       ` Tomasz Moskal
  1 sibling, 0 replies; 14+ messages in thread
From: TJ Luoma @ 2011-07-29  4:50 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Fri, Jul 29, 2011 at 12:04 AM, Bart Schaefer
<schaefer@brasslantern.com> wrote:
> This is sounding awfully familiar.  Oh, it was on zsh-workers, where
> some of the -users crowd would not have seen it.

Including me :-)

For those who might be interested, I'm trying to replace my "dot
source" file[1] with "proper" zshenv and zshrc commands:

[1] http://tj.luo.ma/post/6598593173/dot-source

TjL


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

* Re: how to refer to basename of $0
  2011-07-29  4:04     ` Bart Schaefer
  2011-07-29  4:50       ` TJ Luoma
@ 2011-07-29 11:48       ` Tomasz Moskal
  2011-07-29 14:08         ` Benjamin R. Haskell
  1 sibling, 1 reply; 14+ messages in thread
From: Tomasz Moskal @ 2011-07-29 11:48 UTC (permalink / raw)
  To: zsh-users

On Thu, 2011-07-28 at 21:04 -0700, Bart Schaefer wrote:
> On Jul 28,  9:39pm, TJ Luoma wrote:
> }
> } Is it even possible to set NAME in .zsh* (and have it return
> } 'test.zsh' or are they called too early in the process?
> 
> This is sounding awfully familiar.  Oh, it was on zsh-workers, where
> some of the -users crowd would not have seen it.
> 
> Starts here:
> 
> http://www.zsh.org/mla/workers/2011/msg00159.html
> 
> Interesting branch begins here:
> 
> http://www.zsh.org/mla/workers/2011/msg00163.html
> 
> Particularly:
> 
> http://www.zsh.org/mla/workers//2011/msg00172.html

Thanks for the links, but I am still baffled -  basename $0  is working
here without any problems:

% cat ~/.zshenv
unsetopt function_argzero
name=`basename $0`

% cat ./foo
#!/bin/zsh
. ~/.zshenv
echo $name
exit 0

% ./foo
foo

Obviously it stops when I comment out  unsetopt function_argzero  but
with it in place it there is no problems with reporting the script name
-  zsh -i / -l / -f  make no difference.

Only options I have set in .zshrc are to do with history, basic
completion and prompt (what can I say? I am just getting acquainted with
zsh). Obviously the OPEN_PLAN_OFFICE_NO_VIGILANTE_ATTACKS option is gone
as well. Global zshenv has nothing but path and umask. So as you can see
there is no weirdness in any of the files alas  basename $0  do behave
in a different way than described here on on -workers.

What may be the reason of that?


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

* Re: how to refer to basename of $0
  2011-07-29 11:48       ` Tomasz Moskal
@ 2011-07-29 14:08         ` Benjamin R. Haskell
  2011-07-29 22:30           ` Bart Schaefer
  0 siblings, 1 reply; 14+ messages in thread
From: Benjamin R. Haskell @ 2011-07-29 14:08 UTC (permalink / raw)
  To: Tomasz Moskal; +Cc: zsh-users

On Fri, 29 Jul 2011, Tomasz Moskal wrote:

> On Thu, 2011-07-28 at 21:04 -0700, Bart Schaefer wrote:
>> On Jul 28,  9:39pm, TJ Luoma wrote:
>> }
>> } Is it even possible to set NAME in .zsh* (and have it return 
>> } 'test.zsh' or are they called too early in the process?
>>
>> This is sounding awfully familiar.  Oh, it was on zsh-workers, where 
>> some of the -users crowd would not have seen it.
>>
>> Starts here:
>>
>> http://www.zsh.org/mla/workers/2011/msg00159.html
>>
>> Interesting branch begins here:
>>
>> http://www.zsh.org/mla/workers/2011/msg00163.html
>>
>> Particularly:
>>
>> http://www.zsh.org/mla/workers//2011/msg00172.html
>
> Thanks for the links, but I am still baffled -  basename $0  is 
> working here without any problems:
>
> % cat ~/.zshenv
> unsetopt function_argzero
> name=`basename $0`
>
> % cat ./foo
> #!/bin/zsh
> . ~/.zshenv
> echo $name
> exit 0

The point wasn't quite the same (didn't involve "source"-ing .zshenv). 
$0 doesn't work if used inside startup files (.zshenv/.zshrc/.zprofile). 
When you source it manually, it's not treated specially.

Just wanted to note that the '%x' that I pointed out does work, though:

## as the first line of .zshenv (so, will be run when starting zsh)
$ sed 1q ~/.zshenv
echo in .zshenv 0=$0 %x=${(%):-%x}

## results in:
$ zsh
in .zshenv 0=zsh %x=/home/bhaskell/.zshenv

-- 
Best,
Ben


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

* Re: how to refer to basename of $0
  2011-07-29 14:08         ` Benjamin R. Haskell
@ 2011-07-29 22:30           ` Bart Schaefer
  2011-07-30 19:43             ` Greg Klanderman
  0 siblings, 1 reply; 14+ messages in thread
From: Bart Schaefer @ 2011-07-29 22:30 UTC (permalink / raw)
  To: zsh-users

On Jul 29, 10:08am, Benjamin R. Haskell wrote:
} Subject: Re: how to refer to basename of $0
}
} On Fri, 29 Jul 2011, Tomasz Moskal wrote:
} 
} > On Thu, 2011-07-28 at 21:04 -0700, Bart Schaefer wrote:
} >> On Jul 28,  9:39pm, TJ Luoma wrote:
} >> }
} >> } Is it even possible to set NAME in .zsh* (and have it return 
} >> } 'test.zsh' or are they called too early in the process?
} >>
} >> This is sounding awfully familiar.  Oh, it was on zsh-workers, where 
} >> some of the -users crowd would not have seen it.
} >
} > Thanks for the links, but I am still baffled -  basename $0  is 
} > working here without any problems:
} 
} The point wasn't quite the same (didn't involve "source"-ing .zshenv). 
} $0 doesn't work if used inside startup files (.zshenv/.zshrc/.zprofile). 
} When you source it manually, it's not treated specially.
} 
} Just wanted to note that the '%x' that I pointed out does work, though:
} 
} ## as the first line of .zshenv (so, will be run when starting zsh)
} $ sed 1q ~/.zshenv
} echo in .zshenv 0=$0 %x=${(%):-%x}

And I just wanted to point out that ${(%):-%x} doesn't solve the problem
being discussed in the zsh-workers thread I referenced; in the workers
thread the desire is to find the name of the calling script, which has
not yet been assigned to $0 at the time .zshenv is read.

This led to the patch proposed here:

http://www.zsh.org/mla/workers/2011/msg00180.html

-- which has not yet been applied, the discussion having broken off at
this point:

http://www.zsh.org/mla/workers/2011/msg00183.html


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

* Re: how to refer to basename of $0
  2011-07-29 22:30           ` Bart Schaefer
@ 2011-07-30 19:43             ` Greg Klanderman
  0 siblings, 0 replies; 14+ messages in thread
From: Greg Klanderman @ 2011-07-30 19:43 UTC (permalink / raw)
  To: zsh-users

>>>>> On July 29, 2011 Bart Schaefer <schaefer@brasslantern.com> wrote:

> This led to the patch proposed here:

> http://www.zsh.org/mla/workers/2011/msg00180.html

> -- which has not yet been applied, the discussion having broken off at
> this point:

> http://www.zsh.org/mla/workers/2011/msg00183.html

Sorry about dropping this.. I do plan to get back to that and submit a
patch including doc updates sometime, been a bit busy since my company
got acquired this spring..

Greg


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

end of thread, other threads:[~2011-07-30 19:51 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-28 22:55 how to refer to basename of $0 TJ Luoma
2011-07-28 23:54 ` Tomasz Moskal
2011-07-29  0:24 ` Phil Pennock
2011-07-29  1:30   ` Tomasz Moskal
2011-07-29  0:44 ` Benjamin R. Haskell
2011-07-29  1:39   ` TJ Luoma
2011-07-29  2:06     ` Tomasz Moskal
2011-07-29  4:04     ` Bart Schaefer
2011-07-29  4:50       ` TJ Luoma
2011-07-29 11:48       ` Tomasz Moskal
2011-07-29 14:08         ` Benjamin R. Haskell
2011-07-29 22:30           ` Bart Schaefer
2011-07-30 19:43             ` Greg Klanderman
2011-07-29  3:05   ` TJ Luoma

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