5

If I ask bash to echo the -1th argument it prints hb1:

echo $-1
hb1

Why? What is it accessing?

2
  • 2
    $- gets the current shell options (which is apparently "hb"). What did you expect it to do? Jun 22, 2019 at 19:21
  • I thought it might loop round like some arrays do. Thanks.
    – Neil
    Jun 22, 2019 at 19:23

1 Answer 1

20

You are not asking it to print the 1st argument, that would be: $1.

What you are asking for is a special parameter:

-

($-, a hyphen.) Expands to the current option flags as specified upon invocation, by the set builtin command, or those set by the shell itself (such as the -i option).

So your options are: hb

Then you see the 1 you've added is printed afterwards (hence hb1).


If you are looking to get the last argument (Not sure if that is what you meant by -1 argument), you can use Shell Parameter Expansion in the following form:

$ set -- one two three
$ echo "${@: -1}"
three
4
  • 8
    ${!#} is also the value of the last parameter, using indirect expansion. Jun 22, 2019 at 19:30
  • 2
    Hmmm: ${@:~0} and eval echo \$$# are also the last argument. :-)
    – user232326
    Jun 22, 2019 at 20:32
  • @Isaac If you're lucky, that's true. If IFS contains any digits in the value $# expands to, not so much. Always safer to quote; eval "echo \"\$$#\"" is more reliable. To see the failure for yourself: IFS=1234567890; set -- one two three; eval echo \$$# only outputs $. Jun 23, 2019 at 20:10
  • @CharlesDuffy Yes, you are correct, my mistake. But it is also required to allow positional parameters at position 10 and up. For a really reliable solution add {} : IFS=1234567890; set -- {a..w}; eval echo \"\$\{"$#"\}\" ;-)
    – user232326
    Jun 23, 2019 at 20:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.