目录
一、eval
1.把字符串当命令执行
bash-4.2$ # script="cat getopt.sh"
bash-4.2$ # eval $script
#!/bin/bash
rr=$(getopt ab:cd -a yyy -b test1 -cd test2 test3)
echo $rr
bash-4.2$ # eval "ll .."
total 3780
-rw-r--r-- 1 root root 4096 Mar 13 2020 ?
drwxr-xr-x 2 root root 4096 Dec 24 2020 bin
drwxr-xr-x 3 root root 4096 Mar 2 2020 boot
drwxr-x--- 3 root root 4096 Jun 25 14:46 build
drwxr-xr-x 18 root root 3700 Jun 25 10:25 dev
drwxr-x--- 3 root root 4096 Jun 21 14:41
……
字符串中可以含变量
bash-4.2$ # pathtemp=/
bash-4.2$ # eval "ll $pathtemp"
total 3780
-rw-r--r-- 1 root root 4096 Mar 13 2020 ?
drwxr-xr-x 2 root root 4096 Dec 24 2020 bin
drwxr-xr-x 3 root root 4096 Mar 2 2020 boot
drwxr-x--- 3 root root 4096 Jun 25 14:46 build
drwxr-xr-x 18 root root 3700 Jun 25 10:25 dev
……
2.变量套用(最多两层)
bash-4.2$ # t=tttt
bash-4.2$ # tttt=tttttt
bash-4.2$ # eval echo \$$t
tttttt
二、getopt
此函数是用来分析脚本参数的,用法:
getopt <optstring> <parameters>
getopt [options] [--] <optstring> <parameters>
getopt [options] -o|--options <optstring> [options] [--] <parameters>
其中,optstring是要分析的参数,parameters是实际的参数列表
1.分析短参数,参数无value
不在要分析的参数里会报无效参数(-q可隐藏错误输出),不带value的参数后面的value会统一放到 - - 后面
bash-4.2$ # getopt abcd -a aa -b bb -cd -e
getopt: invalid option -- 'e'
-a -b -c -d -- aa bb
bash-4.2$ # getopt -q abcd -a aa -b bb -cd -e
-a -b -c -d -- 'aa' 'bb'
2.分析短参数,带value
带value的参数需要加冒号:
bash-4.2$ # getopt a:b:cd -a aa -b bb -cd ccdd
-a aa -b bb -c -d -- ccdd
或者这样(上面是简化版)
bash-4.2$ # getopt -q -o 'abcd' -- -a aa -b bb -cd -e
-a -b -c -d -- 'aa' 'bb'
!!!注意,如果加引号,结果会不及预期:
bash-4.2$ # getopt -o 'a:bcd' -- '-a aaa -b bbb'
-a ' aaa -b bbb' --
3.分析长参数
必须制定短参数为空
长参数带value
bash-4.2$ # getopt -o '' -l "nation:,height:" -- --nation=China --height=168
--nation 'China' --height '168' --
长参数不带value
bash-4.2$ # getopt -o '' -l "nation:,height" -- --nation=China --height=168
getopt: option '--height' doesn't allow an argument
--nation 'China' --
bash-4.2$ # getopt -o '' -l "nation:,height" -- --nation=China --height
--nation 'China' --height --
bash-4.2$ # getopt -q -o '' -l "nation:,height" -- --nation=China --height=168
--nation 'China' --
三、set
set比较简单,就是将$1 $2 $3……设为固定的值
bash-4.2$ # cat test.sh
#!/bin/bash
echo $1 $2 $3
set -- aa bb cc
echo $1 $2 $3
bash-4.2$ # sh test.sh a b c
a b c
aa bb cc
上例中,脚本传参本来是a b c ,但set命令将三个参数设置为 aa bb cc 后就会将原来的参数覆盖掉
四、shift
将参数左移n个,也可以理解为删除前n个参数
bash-4.2$ # cat test.sh
#!/bin/bash
set -- aa bb cc dd ee ff gg hh
echo $1 $2 $3 $4 $5 $6 $7 $8
shift 3
echo $1 $2 $3 $4 $5 $6 $7 $8
bash-4.2$ # sh test.sh
aa bb cc dd ee ff gg hh
dd ee ff gg hh
五、参数处理脚本实例
文件内容如下
#!/bin/bash
function handle_input()
{
local args=$(getopt -o "" -l "nation:,height:,is-student:,english-level:" -- "$@")
eval set -- "${args}"
while true
do
case "${1}" in
--nation)
_NATION=${2}
shift 2
;;
--height)
_HEIGHT=${2}
shift 2
;;
--is-student)
_IS_STUDENT=${2}
shift 2
;;
--english-level)
_ENGLISH_LEVEL=${2}
shift 2
;;
--)
shift
break
;;
esac
done
}
function main()
{
handle_input $@
if [ "${_NATION}" != "" ]
then
eval echo "nation is ${_NATION}"
fi
if [ "${_HEIGHT}" == "" ]
then
echo "height is null"
fi
if [ "${_IS_STUDENT}" == false ]
then
echo "is not student"
fi
if [ "${_ENGLISH_LEVEL}" == "" ]
then
echo "can't speak english"
fi
}
main $@
执行如下命令,输出如预期:
bash-4.2$ # sh script-test.sh --nation China --is-student false
nation is China
height is null
is not student
can't speak english