我的脚本:
#! /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"
case "${VERB}" in
(exec)
shift "$#" # remove args passed to this fn
# Execute a command in a running container.
if [ -n "${SERVICE}" ]; then
${CMD} "${VERB}" "${SERVICE}" "$@"
else
echo "## Err: You must specify service name..."
exit 1
fi
;;
esac
}
compose_fn "${1}" "${2}" "${3}"
以下错误让我很难受:
$ ./tst.sh dev exec django sh
+ compose_fn dev exec django
+ local ENV=dev
+ local VERB=exec
+ local SERVICE=django
+ local 'CMD=docker-compose -f dev.yml'
+ case "${VERB}" in
+ shift 3
+ '[' -n django ']'
+ docker-compose -f dev.yml exec django
Execute a command in a running container
Usage: exec [options] [-e KEY=VAL...] SERVICE COMMAND [ARGS...]
Options:
....
我的错误在哪里?怎样才能做得更好呢?
据我所知,我已将 4 个参数传递[dev, exec, django, sh]
给脚本,然后在脚本中删除了 3 个 ( shift 3
),因此sh
应该保留在$@
var 中。
答案1
与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 "$@"
我还使用了小写变量名,这样就不会意外使用系统或特殊 shell 变量(ENV
例如,某些 shell 在某些情况下使用的变量),并且我删除了所有不需要的引号和大括号。
我还将命令放入一个数组中,以便我们可以正确引用 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}
将退出 shell,并显示word
ifparameter
未设置或为空定义的消息。 shellbash
会将其格式化为
script.sh: line 9: 3: ## Err: You must specify service name...
有关的: