从右移 bash 参数

dim*_*414 3 bash

我有一个脚本,用户将为其添加前缀而不是附加参数,即他们可能会调用command Ccommand B Ccommand A B C等。

我希望能够简单地从右侧移动这些参数,就像使用shift.

我正在成像一个shift-right行为如下的命令:

echo "$@"    # A B C
shift-right
echo "$@"    # A B
shift-right
echo "$@"    # A
shift-right
echo "$@"    # 
echo "$#"    # 0
Run Code Online (Sandbox Code Playgroud)

有没有一种干净的方法来实现这一点?我知道我可以解决它,但类似shift的解决方案会更好更简单。


作为对 XY 问题评论的回应,我的特定用例是一个命令,它接受一个端口或一个主机和端口,例如command 123command remotehost 123。我不希望用户必须以相反的顺序指定这些(端口然后是主机)。

说这样的话(显然未经测试)会相当干净:

port=${@: -1}
shift-right
host=${1:-localhost}
Run Code Online (Sandbox Code Playgroud)

真的,我对这个问题很好奇,即使有更好的方法来解决这个特定的例子。

这是一种相当干净的方法来处理没有 的两个参数的情况shift-right,仅供参考:

port=${@: -1}
host=${2:+$1}
host=${host:-localhost}
Run Code Online (Sandbox Code Playgroud)

但希望你能理解随着参数数量的增加,它变得更加笨拙。

小智 8

如果位置参数列表是:

$ set -- 0wer 1wdfg 2erty 333 4ffff 5s5s5
Run Code Online (Sandbox Code Playgroud)

然后这将打印没有最后一个的参数:

$ echo "${@:1:$#-1}"
0wer 1wdfg 2erty 333 4ffff
Run Code Online (Sandbox Code Playgroud)

当然,参数也可以设置为:

$ set -- "${@:1:$#-1}"
$ echo $@
0wer 1wdfg 2erty 333 4ffff
Run Code Online (Sandbox Code Playgroud)

这适用于 bash 2.0 或更高版本。

对于其他更简单的 shell,您需要一个(有点棘手的)循环来删除最后一个参数:

unset b; for a; do set -- "$@" ${b+"$b"}; shift; b="$a"; done
Run Code Online (Sandbox Code Playgroud)