所以我想做一个"程序"这有助于像yum命令和其他命令...当程序完成后我想把它放在/ usr / bin中,名字是" dafs"
我用这个例子测试了文件名为dafs
#!/bin/bash
$1 $2 $3
function yum {
function maintenance {
yum -y update
yum -y upgrade
yum clean all
}
function download {
yum -y install --downloadonly $3
}
}
但是当我运行./dafs yum maintenance
或./dafs yum download http
时,我猜它不起作用,因为语法不正确..
那么,我如何将参数传递给函数或子函数,如上例所示?
答案 0 :(得分:6)
定义子命令的最佳实践方法是使用带前缀的命名空间和“启动器”功能。例如git
就是这样做的(对git-foo
和git-bar
使用git foo
和git bar
命令。
这里,我使用双下划线而不是单个短划线作为分隔符,因为下划线(与破折号不同)在POSIX sh标准中定义为函数名称内的有效。
yum__maintenance() {
command yum -y update
command yum -y upgrade
command yum clean all
}
yum__download() {
command yum -y install --downloadonly "$@"
}
yum() {
local cmdname=$1; shift
if type "yum__$cmdname" >/dev/null 2>&1; then
"yum__$cmdname" "$@"
else
command yum "$cmdname" "$@" # call the **real** yum command
fi
}
# if the functions above are sourced into an interactive interpreter, the user can
# just call "yum download" or "yum maintenance" with no further code needed.
# if invoked as a script rather than sourced, call function named on argv via the below;
# note that this must be the first operation other than a function definition
# for $_ to successfully distinguish between sourcing and invocation:
[[ $_ != $0 ]] && return
# make sure we actually *did* get passed a valid function name
if declare -f "$1" >/dev/null 2>&1; then
# invoke that function, passing arguments through
"$@" # same as "$1" "$2" "$3" ... for full argument list
else
echo "Function $1 not recognized" >&2
exit 1
fi
注意事项:
"$@"
扩展为传递给范围中当前项的参数的完整列表,保留参数边界并避免全局扩展(与$*
和不带引号的$@
不同)。shift
弹出列表前面的第一个参数($1
),使新值"$@"
比旧列表短一些。command
内置函数会导致调用真实yum
命令,而不是仅在没有子命令时再次递归yum
函数。declare -f funcname
将返回true(并打印该函数的定义)。相反,type
如果传递任何类型的runnable命令,则返回true。因此,使用type "yum__$cmdname"
允许将yum__foo
定义为外部脚本或任何其他类型的命令,而不仅仅是函数,而稍后完成的declare -f "$1"
仅允许运行函数。 / LI>
最后要考虑的是,如果你不打算支持被采购,那么将遗漏yum
函数,但扩展你的启动器以识别子命令:
if declare -f "${1}__$2" >/dev/null; then
func="${1}__$2"
shift; shift # pop $1 and $2 off the argument list
"$func" "$@" # invoke our named function w/ all remaining arguments
elif declare -f "$1" >/dev/null 2>&1; then
"$@"
else
echo "Neither function $1 nor subcommand ${1}__$2 recognized" >&2
exit 1
fi
在这种情况下,始终搜索前两个参数命名的子命令,后跟仅由第一个参数命名的函数。
答案 1 :(得分:2)
您也可以这样做:
#!/bin/sh
yum() {
if [ "$1" = "maintenance" ]; then
command yum -y update
command yum -y upgrade
command yum clean all
elif [ "$1" = "download" ]; then
command yum -y install --downloadonly "$2"
else
echo "Invalid arg..."
fi
}
if [ "$1" = "yum" ];then
shift
yum "$@"
fi
现在,您可以使用./dafs yum maintenance
或./dafs yum download http
。