8. 用getopts处理命令行选项:
这里的getopts命令和C语言中的getopt几乎是一致的,因为脚本的位置参量在有些时候是失效的,如ls -lrt等。这时候-ltr都会被保存在$1中,而我们实际需要的则是三个展开的选项,即-l、-r和-t。见如下带有getopts的示例脚本:
/> cat > test3.sh
#!/bin/sh
while getopts xy options #x和y是合法的选项,并且将-x读入到变量options中,读入时会将x前面的横线去掉。
do
case $options in
x) echo "you entered -x as an option" ;;
y) echo "you entered -y as an option" ;;
esac
done
/> ./test3.sh -xy
you entered -x as an option
you entered -y as an option
/> ./test3.sh -x
you entered -x as an option
/> ./test3.sh -b #如果输入非法选项,getopts会把错误信息输出到标准错误。
./test3.sh: illegal option -- b
/> ./test3.sh b #该命令不会有执行结果,因为b的前面有没横线,因此是非法选项,将会导致getopts停止处理并退出。
/> cat > test4.sh
#!/bin/sh
while getopts xy options 2>/dev/null #如果再出现选项错误的情况,该重定向会将错误输出到/dev/null。
do
case $options in
x) echo "you entered -x as an option" ;;
y) echo "you entered -y as an option" ;;
\?) echo "Only -x and -y are valid options" 1>&2 # ?表示所有错误的选项,即非-x和-y的选项。
esac
done
/> . ./test4.sh -g #遇到错误的选项将直接执行\?)内的代码。
Only -x and -y are valid options
/> . ./test4.sh -xg
you entered -x as an option
Only -x and -y are valid options
/> cat > test5.sh
#!/bin/sh
while getopts xyz: arguments 2>/dev/null #z选项后面的冒号用于提示getopts,z选项后面必须有一个参数。
do
case $arguments in
x) echo "you entered -x as an option." ;;
y) echo "you entered -y as an option." ;;
z) echo "you entered -z as an option." #z的后面会紧跟一个参数,该参数保存在内置变量OPTARG中。
echo "\$OPTARG is $OPTARG.";
;;
\?) echo "Usage opts4 [-xy] [-z argument]"
exit 1 ;;
esac
done
echo "The number of arguments passed was $(( $OPTIND - 1 ))" #OPTIND保存一下将被处理的选项的位置,他是永远比实际命令行参数多1的数。
/> ./test5.sh -xyz foo
you entered -x as an option.
you entered -y as an option.
you entered -z as an option.
$OPTARG is foo.
The number of arguments passed was 2
/> ./test5.sh -x -y -z boo
you entered -x as an option.
you entered -y as an option.
you entered -z as an option.
$OPTARG is boo.
The number of arguments passed was 4
9. eval命令与命令行解析:
eval命令可以对命令行求值,做Shell替换,并执行命令行,通常在普通命令行解析不能满足要求时使用。
/> set a b c d
/> echo The last argument is \$$#
The last argument is $4
/> eval echo The last argument is \$$# #eval命令先进行了变量替换,之后再执行echo命令。
The last argument is d