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.
getoptsor similar (e.g./usr/bin/getoptfrom theutil-linuxpackage if you want to support --long options as well as short).getoptin scripts. It's not even part ofbash, so it introduces an external dependency. Super un-portable. @casutil-linux, versions ofgetoptare known to be buggy and unsafe to use.getoptfromutil-linuxis 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_longshell function usesperland theGetopt::Longperl module, which are also external dependencies.