在使用 getopt
解析命令行参数时,可以处理像 -t 1.1
这样的参数。以下是一个示例脚本,展示了如何使用 getopt
来解析这些参数。
#!/bin/bash
# 使用 getopt 来解析命令行参数
TEMP=$(getopt -o t: --long tag: -n 'example.bash' -- "$@")
# 检查 getopt 的返回值,如果 getopt 返回一个错误代码,那么脚本退出
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# 重新设置被解析的参数,将 getopt 生成的参数重新设置到 $@ 中。
eval set -- "$TEMP"
# 初始化变量
TAG_VALUE=""
# 解析选项
while true ; do
case "$1" in
-t|--tag) # 如果匹配到 `-t` 或 `--test`,则将其参数保存到 `TEST_VALUE` 中,并用 `shift 2` 移动到下一个参数。
TAG_VALUE="$2"; shift 2 ;;
--) shift ; break ;; # 遇到 `--` 时结束选项解析。
*) echo "Internal error!" ; exit 1 ;; # 捕捉任何未知的选项。
esac
done
# 输出解析结果
echo "Tag value: $TAG_VALUE"
# 剩余的非选项参数
echo "Remaining arguments: $@"
-
-o t:
: 短选项t
需要一个参数。 -
--long tag:
: 长选项--tag
需要一个参数。 -
-n 'example.bash'
: 为错误信息指定脚本名称。 -
-- "$@"
: 处理所有传递给脚本的参数。 -
getopt
返回的字符串是处理后的参数列表,将其赋值给变量TEMP
。这些处理后的参数可能包括一些添加的标记和分隔符(例如--
)以帮助进一步的参数解析。 -
--
是一个特殊标记,用于告诉getopt
解析器,后面的所有内容都是非选项参数,即使它们看起来像选项。例如,-t
是一个选项,但-- -t
后面的-t
会被视为一个普通参数而不是选项。
在 getopt
解析命令行参数的过程中,eval set -- "$TEMP"
这一行的目的是重新设置脚本的参数列表,以便可以按照标准的方式解析和处理这些参数。
-
eval
是一个 shell 内建命令,它会重新计算(或执行)传递给它的字符串。当你使用eval set -- "$TEMP"
时,eval
会将$TEMP
的内容作为命令来执行。
例如:expression="3 + 4" eval result=$((expression)) echo "Result: $result"
这段脚本将计算
3 + 4
的结果并输出Result: 7
。cmd="ls -l" eval $cmd
这段脚本将执行
ls -l
命令,列出当前目录的详细信息。 -
set --
会重置位置参数 ($1
,$2
, 等)。并确保后续的参数被视为普通参数而不是选项。当后面跟上"$TEMP"
的内容时,它会将这些内容设置为新的位置参数。
例如:set -- -t somefile.txt echo $1 # 输出: -t echo $2 # 输出: somefile.txt
当你使用 getopt
来解析命令行参数时,返回的字符串中可能包含一些复杂的内容,例如引号和空格。为了正确处理这些内容并重新设置脚本的参数列表,使用 eval
可以确保这些参数被正确解析和传递。如果你直接使用 set -- "$TEMP"
,则 $TEMP
的内容会被视为单个字符串参数,而不是多个参数。
例如:
#!/bin/bash
TEMP=$(getopt -o t: --long test: -n 'example.sh' -- "$@")
if [ $? != 0 ]; then
echo "Terminating..." >&2
exit 1
fi
set -- "$TEMP"
echo "Before eval: $TEMP"
echo "\$1: $1"
echo "\$2: $2"
echo "\$3: $3"
eval set -- "$TEMP"
echo "After eval: $TEMP"
echo "\$1: $1"
echo "\$2: $2"
echo "\$3: $3"
输出:
$ ./example.sh -t "value with spaces" otherarg
Before eval: -t 'value with spaces' -- 'otherarg'
$1: -t 'value with spaces' -- 'otherarg'
$2:
$3:
After eval: -t 'value with spaces' -- 'otherarg'
$1: -t
$2: value with spaces
$3: --
getopt
返回的字符串已经包含了所有解析后的选项和参数,这样可以确保参数的顺序和格式符合预期。通过 eval set -- "$TEMP"
,你可以将这些解析后的参数重新传递给脚本的参数列表,使得后续的 while
循环可以正确地解析这些参数。
shift 命令用于对参数的移动(左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理。
例如:依次读取输入的参数并打印参数个数
#!/bin/bash
while [ $# != 0 ]; do
echo "prama is $1, prama size is $#"
shift
done
输入如下命令运行:
./shift_test.sh a b c
prama is a, prama size is 3
prama is b, prama size is 2
prama is c, prama size is 1
每次运行 shift(不带参数的),销毁一个参数,后面的参数前移。
Shift 命令一次移动参数的个数由其所带的参数指定。例如当 shell 程序处理完前九个命令行参数后,可以使用 shift 9 命令把 $10 移到 $1。