I have a script that users will prefix, rather than append, arguments to, i.e. they might call command C
, command B C
, command A B C
, and so on.
I'd like to be able to simply shift over these arguments from the right, the same way you might shift them from the left with shift
.
I'm imaginging a shift-right
command that behaves like so:
echo "$@" # A B C
shift-right
echo "$@" # A B
shift-right
echo "$@" # A
shift-right
echo "$@" #
echo "$#" # 0
Is there a clean way to accomplish this? I know I can work around it, but a shift
-like solution would be much nicer and simpler.
In response to the XY-problem comment, my specific use case is a command that takes either a port or a host and port, e.g. command 123
or command remotehost 123
. I don't want users to have to specify these in reverse order (port then host).
It would be fairly clean to say something like (untested, obviously):
port=${@: -1}
shift-right
host=${1:-localhost}
Really though, I'm curious about the question in general, even if there's a better way to solve this specific example.
Here's one reasonably clean way to handle the two-argument case without shift-right
, just for reference:
port=${@: -1}
host=${2:+$1}
host=${host:-localhost}
But hopefully you can appreciate how that becomes more cludgy as the number of arguments increases.
getopts
or similar (e.g./usr/bin/getopt
from theutil-linux
package if you want to support --long options as well as short).getopt
in scripts. It's not even part ofbash
, so it introduces an external dependency. Super un-portable. @casutil-linux
, versions ofgetopt
are known to be buggy and unsafe to use.getopt
fromutil-linux
is available for and/or can be compiled for other unixes. if you want/need --long options in shell scripts, it's really the only choice available. BTW, even SC'sgetopts_long
shell function usesperl
and theGetopt::Long
perl module, which are also external dependencies.