1

file a

#!/bin/zsh
echo $*
echo $0

echo ---

echo $argv
echo $argv[0]

when the command is

./a 1 2

It shows:

1 2
./a
---

[0]

When the command is:

zsh ./a 1 2

It shows:

1 2
./a
---
1 2

Why the whether a 'zsh' being as an explict command can change the result ? And why argv[0] is not assigned?

1 Answers1

4

$0 is not a positional parameter, it's not part of $@, it's the name of the script/function. $*, $@ and $argv are all the same normal (non-sparse) array of the positional parameters and all array indices start at 1 in zsh unless you enable the ksharrays option.

But if you enable the ksharrays option for array indices to start at 0, you'll notice that $argv[0] or ${@[0]} is the first positional parameter: $1.

Your confusion may be coming from arrays of ksh93-like shells (including bash), where ${@:0:1} is $0 even though the expansion of "$@" doesn't include $0. That confusion is the result of Korn choosing to make its shell array indices start at 0 even though the Bourne shell which it is based on, and most other shells and tools used by the shell chose to have their array indices start at 1.

More on that at Is there a reason why the first element of a Zsh array is indexed by 1 instead of 0?

  • Could you please tell me why in the second case, the value of the script name is not assigned to argv[0]? – Tom Tsai Apr 14 '20 at 10:05
  • As I said, because $argv contains the positional parameters (and the script name is not a positional parameter) and also because array indices start at 1, not 0, there can't be a value for indice 0. – Stéphane Chazelas Apr 14 '20 at 10:08
  • Please look at http://zsh.sourceforge.net/Doc/zsh_us.pdf Page 12: exec part. Then, why after running command: exec -a newargv0 zsh, it's still nothing but a newline as a output by echo $argv[0] . So do you mean argv[0] will never be set, but $0 will? If so, why there is argv[0] in the document. – Tom Tsai Apr 14 '20 at 10:28
  • That document refers to the char *argv[] C language array that zsh's main() routine receives, which is also the second argument to the execve() system call, not the $argv[0] of zsh language. See man 2 execve – Stéphane Chazelas Apr 14 '20 at 10:39