What's a better way to implement print_last_arg
?
#!/bin/sh
print_last_arg () {
eval "echo \${$#}" # this hurts
}
print_last_arg foo bar baz
# baz
(If this were, say, #!/usr/bin/zsh
instead of #!/bin/sh
I'd know what to do. My problem is finding a reasonable way to implement this for #!/bin/sh
.)
EDIT: The above is only a silly example. My goal is not to print the last argument, but rather to have a way to refer to the last argument within a shell function.
EDIT2: I apologize for such an unclearly worded question. I hope to get it right this time.
If this were /bin/zsh
instead of /bin/sh
, I could write something like this
#!/bin/zsh
print_last_arg () {
local last_arg=$argv[$#]
echo $last_arg
}
The expression $argv[$#]
is an example of what I described in my first EDIT as a way to refer to the last argument within a shell function.
Therefore, I really should have written my original example like this:
print_last_arg () {
local last_arg=$(eval "echo \${$#}") # but this hurts even more
echo $last_arg
}
...to make it clear that what I'm after is a less awful thing to put to the right of the assignment.
Note, however, that in all the examples, the last argument is accessed non-destructively. IOW, the accessing of the last argument leaves the positional arguments as a whole unaffected.
var=$( eval echo \${$#})
toeval var=\${$#}
- the two are nothing alike. – mikeserv Jan 24 '16 at 00:18shift
andset -- ...
based solutions might be destructive unless used in functions where they are harmless too. – jlliagre Jan 24 '16 at 01:53eval "var=\${$#}"
when compared tovar=${arr[evaled index]}
except that$#
is a guaranteed safe value. why copy the whole set then destroy it when you could just index it directly? – mikeserv Jan 25 '16 at 04:42