С помощью shift "$#"
вы полностью очищаете $@
. $@
в функции отделено от $@
в основном скрипте. Поскольку вы точно знаете, сколько элементов сценария $@
вам нужно использовать и убрать в функцию, почему бы вам просто не передать все аргументы в функцию, а затем убрать первые три?
#! /bin/bash --
set -x
## docker-compose wrapper
compose_fn() {
local env="$1"
local verb="$2"
local service="$3"
local cmd=( docker-compose -f "$env.yml" )
shift 3 # we've now used up three arguments
case $verb in
exec)
# Execute a command in a running container.
if [ -n "$service" ]; then
"${cmd[@]}" "$verb" "$service" "$@"
else
echo '## Err: You must specify service name...' >&2
exit 1
fi
;;
*)
printf 'Unknown verb: %s\n' "$verb" >&2
exit 1
esac
}
compose_fn "$@"
Я также использовал имена переменных нижнего -регистра, чтобы никакие системные или специальные переменные оболочки не использовались случайно(ENV
— это то, что некоторые оболочки используют при некоторых обстоятельствах, например ), и я удалены все ненужные кавычки и фигурные скобки.
Я также поместил команду в массив, чтобы мы могли правильно указать имя файла YAML в кавычках.
Вы также можете просто переместить настройку трех переменных за пределы функции, в зависимости от того, как выглядит остальная часть скрипта и имеет ли это вообще какой-либо смысл. Тогда эти три переменные станут глобальными в сценарии.
#! /bin/bash --
set -x
## docker-compose wrapper
compose_fn() {
local cmd=( docker-compose -f "$env.yml" )
case $verb in
exec)
# Execute a command in a running container.
if [ -n "$service" ]; then
"${cmd[@]}" "$verb" "$service" "$@"
else
echo '## Err: You must specify service name...' >&2
exit 1
fi
;;
*)
printf 'Unknown verb: %s\n' "$verb" >&2
exit 1
esac
}
env="$1"
verb="$2"
service="$3"
shift 3
compose_fn "$@"
Вы также можете обойти тест [ -n "$service" ]
с помощью
service=${3:?'## Err: You must specify service name...'}
Расширение параметра ${parameter:?word}
закроет оболочку с сообщением, определенным word
, если parameter
не установлено или пусто. Оболочка bash
отформатирует это как
script.sh: line 9: 3: ## Err: You must specify service name...
Связанные: