Я бы добавил это как комментарий, но мне не хватает репутации, и ответ все равно получился немного длиннее. Надеюсь, это не против.
Как сказал @func:
last_arg = "$ {!} #"
Как это работает:
$ {! PARAM} указывает на уровень косвенности. Вы не ссылаетесь на PARAM , а на значение, сохраненное в PARAM (представьте PARAM как указатель на значение).
$ {#} расширяется до количества параметров (Примечание: $ 0 - имя скрипта - здесь не учитывается).
Рассмотрим следующее выполнение:
$./myscript.sh p1 p2 p3
А в myscript.sh
#!/bin/bash
echo "Number of params: ${#}" # 3
echo "Last parameter using '\${!#}': ${!#}" # p3
echo "Last parameter by evaluating positional value: $(eval LASTP='$'${#} ; echo $LASTP)" # p3
Следовательно, вы можете думать о $ {! #} как о ярлыке для вышеуказанного использования eval, что в точности соответствует описанному выше подходу - оценивает значение, сохраненное в данном параметре, здесь параметр равен 3 и содержит позиционный аргумент $ 3
Теперь, если вам нужны все параметры, кроме последнего, вы можете использовать удаление подстроки $ {PARAM% PATTERN} , где знак % означает 'удалить самое короткое соответствие шаблон с конца строки '.
Следовательно, в нашем сценарии:
echo "Every parameter except the last one: ${*%${!#}}"
Вы можете прочитать что-то здесь: Расширение параметра