$myscript.sh -host blah -user blah -pass blah
我想将参数传递给它。
我习惯于使用$1
,$2
,$3
....但我想开始命名它们。
$myscript.sh -host blah -user blah -pass blah
我想将参数传递给它。
我习惯于使用$1
,$2
,$3
....但我想开始命名它们。
在sh中,有很多解析参数的方法。 Getopt是不错的选择。这是一个手动解析参数的简单脚本:
#!/bin/sh
# WARNING: see discussion and caveats below
# this is extremely fragile and insecure
while echo $1 | grep -q ^-; do
# Evaluating a user entered string!
# Red flags!!! Don't do this
eval $( echo $1 | sed 's/^-//' )=$2
shift
shift
done
echo host = $host
echo user = $user
echo pass = $pass
echo args = $@
一个示例运行如下:
$ ./a.sh -host foo -user me -pass secret some args
host = foo
user = me
pass = secret
args = some args
$ host=blah user=blah pass=blah myscript.sh
这个功能很好用,变量$host
、$user
和$pass
将会在脚本中可用。
#!/bin/sh
echo host = ${host:?host empty or unset}
echo user = ${user?user not set}
...
declare
而不是 eval
更加安全。 - Dennis Williamson| tr -d '\012'
,因为它不是必需的 - 命令替换会自动修剪所有尾随换行符。 - mklement0declare
而不使用sed
(或eval
)的示例:declare "${1#-}"=$2
。请注意,这种方法无法处理两个或多个前导连字符或嵌入式连字符。此外,在Bash变量名称中不允许使用连字符。可以添加单独的步骤将连字符转换为下划线,因为下划线是允许的:var=${1#-}; declare "${var//-/_}"="$2"
。 - Dennis Williamson这里有一种简单的方法来处理长选项和短选项:
while [[ $1 == -* ]]; do
case "$1" in
-h|--help|-\?) show_help; exit 0;;
-v|--verbose) verbose=1; shift;;
-f) if [[ $# > 1 && $2 != -* ]]; then
output_file=$2; shift 2
else
echo "-f requires an argument" 1>&2
exit 1
fi ;;
--) shift; break;;
-*) echo "invalid option: $1" 1>&2; show_help; exit 1;;
esac
done
获取。/bin/sh
上测试并运行(无需Bash)。 - Top-Mastergetopts
是 Bash 内置命令,而 getopt
是外部实用程序。前者仅适用于短选项(例如 -e
),而后者也适用于长选项(例如 -foo
)。请注意,后者存在一些问题需要解决(较新版本的 getopt
问题较少)。 - Dennis Williamson#!/bin/bash
while echo $1 | grep ^- > /dev/null; do declare $( echo $1 | sed 's/-//g' | sed 's/=.*//g' | tr -d '\012')=$( echo $1 | sed 's/.*=//g' | tr -d '\012'); shift; done
echo host = $host
echo user = $user
echo pass = $pass
您可以这样调用:
script -host=aaa -user=bbb -pass=ccc
结果为:
host = aaa
user = bbb
pass = ccc
这是我的方法:
host=""
user=""
pass=""
while [[ "$#" -gt 0 ]]; do
case $1 in
-h|--host) host="$2"; shift ;;
-u|--user) user="$2"; shift ;;
-p|--pass) pass="$2"; shift ;;
*) echo "Unknown parameter passed: $1" ;;
esac
shift
done