I have just started reading about "$@" and "$*", I wanted to know if I can specifically point to an element in the "$@" array. Like without using any loop, I want to be able to pick element number 3 from "$@". Is there a way of doing this like "$1+@" or something like this? I already know about "${1}" but want to know specifically about "$@" and "$*". I tried searching for it but did not find anything related to this.
Asked
Active
Viewed 200 times
0
Rui F Ribeiro
- 56,709
- 26
- 150
- 232
GypsyCosmonaut
- 4,119
3 Answers
1
$@ is not an array: it's just a list of the arguments. In bash, you can create an array, initialize it with the values from $@ and then use indexing:
declare -a foo=($@)
echo ${foo[2]}
The array indices start from 0, so the above prints the third argument to the script.
NickD
- 2,926
1
It is said that the positional parameters are not an array.
And the way that exists to set them is via set. No other array needs that.
$ set -- one two t33 f44
$ printf '%s\n' "$@"
one
two
t33
f44
But at least in bash (and ksh and zsh), they could be selected just as easy:
$ set -- one two t33 f44
$ echo "${@:2:1}"
two
$ echo "${@:2:2}"
two t33
-
If echo
echo ${@:2:1}gives the outputtwo. So does this mean thatone two t33 f44are set at the indexes1234respectively instead of usual format0123considered in arrays? – GypsyCosmonaut Jul 12 '17 at 01:24 -
And also, why does
echo ${@:0:1}gives the output similar toecho $0i.e the current shell name? – GypsyCosmonaut Jul 12 '17 at 01:30 -
1Yes!. That's the usual numbering of positional parameters as $0 is (most of the time) the name of the running script/program. Just do an
echo $0to see it. @GypsyCosmonaut – Jul 12 '17 at 01:31 -
1Well, as the zero index is the name of the executing script/shell, it must be what should be printed by asking for it with
echo ${@:0:1}. Doesn't it? @GypsyCosmonaut – Jul 12 '17 at 01:33 -
1
${parameter:offset:length}is substring expansion in general, but for@it is treated differently:${@:offset:length}you getlengthpositional parameters beginning atoffset. – NickD Jul 12 '17 at 01:34 -
This
set -- one two t33 f44; echo "${@:2:2}"prints the exact same values as this other doesarr=(one two t33 f44); echo "${arr[@]:1:2}". I really fail to see any important difference between the two (except the index numbering). @Nick – Jul 12 '17 at 01:45 -
I was quoting from the bash man page, but you are right: there is no difference for non-negative offsets. The "different treatment" arises only when the offset is negative (this is untested though, so I may have misunderstood). – NickD Jul 12 '17 at 01:48
-
In bash/ksh/zsh, the negative numbers work the same. The last element is -1, the rest follows that. For example:
zsh -c 'set -- one two t33 f44; echo "${@: -3:2}"'will printf44 f55. The same will be printed with this:ksh -c 'arr=(zero one two t33 f44 f55); echo "${arr[@]: -3:2}"'Just mind the required space before the negative number and observe that I added azeroelement to the second array (which doesn't change the result if omited). It still seems quite similar to me (in the three shells tested). @Nick – Jul 12 '17 at 01:55 -
I reread the manpage and I did indeed misunderstand: the difference is between ${param:offset:length} where param is anything but
@orarr[@], in which case negative offsets count characters from the end of the string; vs the two cases@andarr[@]where negative offsets count elements from the end (positional params in the first case, elements of the array in the second). So yes, you are right: these last two give the same results. – NickD Jul 12 '17 at 02:18
0
Essentially, you can't. The thing is that $* and $@ are not arrays; they are simple variables. Thus, it isn't possible to index them.
Their values are just strings, defined in slightly different ways. $1, $2, etc. give you access to the individual components.
Bob Eager
- 3,600
-
1I believe that you should take a look to my answer. There is an easy way of using indexes to read elements of the positional parameters (at least on some shells) – Jul 12 '17 at 01:17
-
My answer does not conflict with that. I was correcting the assumption in the question that the parameters are arrays, that's all. – Bob Eager Jul 12 '17 at 06:38
array=(apple banana orange); printf "%s\n" "${array[1]}"– jasonwryan Jul 12 '17 at 00:40"$1+@"or"$@+1"exist? I think I saw it somewhere, but am not sure because it has been a lot of time. – GypsyCosmonaut Jul 12 '17 at 01:02