我使用的大多数 shell 脚本的语法如下
./shellscript.sh -first_argument_flag <first_argument_value> -second_argument_flag <second_argument_value>
但是 shell 脚本编写者的所有在线资源都只讨论传递位置参数,例如
./shellscript.sh <first_argument_value> <second_argument_value>
随后在脚本中使用"$1"
、"$2"
等。
我想使用第一种更用户友好的语法,而不是位置参数语法。例如,假设我想回显带有标志 -f 的文件名和带有标志 -d 的目录。将此脚本命名为 echofd.sh。我想
./echofd.sh -f myfile.txt -d /my/directory/
产生输出
您的文件是:myfile.txt
您的目录是:/我的/目录/
并且无论 -f 和 -d 在调用脚本时的顺序如何。
答案1
有的是getopts
标准(内置)实用程序在 POSIX shell 中用于解析命令行参数。
您可以使用此模板:
#! /bin/sh -
PROGNAME=$0
usage() {
cat << EOF >&2
Usage: $PROGNAME [-v] [-d <dir>] [-f <file>]
-f <file>: ...
-d <dir>: ...
-v: ...
EOF
exit 1
}
dir=default_dir file=default_file verbose_level=0
while getopts d:f:v o; do
case $o in
(f) file=$OPTARG;;
(d) dir=$OPTARG;;
(v) verbose_level=$((verbose_level + 1));;
(*) usage
esac
done
shift "$((OPTIND - 1))"
echo Remaining arguments: "$@"
就像其他标准命令一样,它以标准方式解析参数。例如,您可以将其称为:
myscript -vvv -f file -d dir other arg
myscript -ffile -ddir -- other arg
看POSIX 规范或您的 shell 手册了解详细信息。
答案2
#!/bin/bash
myfile=''
mydir=''
parse_args() {
case "$1" in
-d)
mydir="$2"
;;
-f)
myfile="$2"
;;
*)
echo "Unknown or badly placed parameter '$1'." 1>&2
exit 1
;;
esac
}
while [[ "$#" -ge 2 ]]; do
parse_args "$1" "$2"
shift; shift
done