shell参数传递
背景
在脚本,或者shell的function中,常常会有参数的出现,甚至有时会需要选项卡
特殊变量
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。 |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |
“$@” | 参数列表的数组 |
“$*” | 参数列表的集合,为一个字符串 |
后者示例
1 | #! test.sh |
执行
1 | ./test.sh one two three |
输出为
1 | one two three #"$*"的 |
选项卡
前言
在参数仅有一个不需要分类时,使用带一个参数的方式就好,不需要使用选项卡
1 | ./test.sh 10 |
好过只有一种选项的
1 | ./test.sh -n 10 |
选项的说明
1 | -a -b #短选项 |
选项的获取
分两种
- 独立的=getopts=,不支持长选项和可选参数,但是非常简单
- bash自带的=getopt=,支持长选项和可选参数,zsh兼容bash,应该也能用
-
getopts
从参数字符串中 提取
$opt
变量与$OPTARG
变量,
然后 逐个 使用 case 语句(类似C语言的which语句)进行处理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#! .bashrc
function apple(){
while getopts "z:xc" opt #冒号表示z需要有参数
do
case $opt in
z)
echo "z's arg:$OPTARG";; #case后面的双分号不能少
x)
echo "x's choosen";;
c)
echo "c's choosen";;
?)
echo "bad options";;
esac
done
}结果为
1
2
3
4
5
6> apple -z 1 -xcy
z's arg:1
x's choosen
c's choosen
apple:1: bad option: -y #系统的提示
bad options #自定义的提示 -
getopt
实际上就是将短参数分开整理的功能
例如将-abc
转换成-a -b -c
没有特定的$OPTARG
变量
所以常搭配 循环 和 shift 语句,将选项卡逐个放在$1
,这时参数看情况放在$2
或者没有等
总思路就是 将选项卡视为参数 ,然后使用case语句进行处理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34# echo $1
temp=`getopt -o ab:c:: --long along,blong: -- "$@"`
echo $temp
set -- $temp
echo
while [ -n "$1" ]
do
echo "\$1 is $1"
case $1 in
-a|--along)
echo "a's choosen";shift;;
-b|--blong)
echo "b's arg:$2";shift 2;;
-c)
case $2 in
"")
echo "c's choosen";;
*)
echo "c's arg:$2";;
esac;
shift 2;;
--)
shift;
break;;
esac
done
echo "remaining args"
for arg do
echo '-->'"$arg";
done
# for arg in $@
# do
# echo '-->'"$arg"
# done- -o表示短选项,-long表示长选项,-n表示错误,–表示后接正常参数
- 长选项之间用逗号分割
- 一个冒号表示有参数,两个冒号表示有可选参数,长选项没有可选参数
- 可选参数与选项卡没有间隔,如果长选项的可选参数是字符,
那么将不好界定是输入了一个参数还是输入了一个非法的长选项
- 可选参数与选项卡没有间隔,如果长选项的可选参数是字符,
getopt
将参数表的字符串进行加工set --
将加工好的字符串重新设为参数表- 参数表在这里以空格为划分,故
'a b'
不被认为是一个,而分别是'a
和b'
for arg do
这个命令的格式最好不要学
使用
1
./me.sh -ac2 -b 1 --along --blong 3 'a b'
结果为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15-a -c '2' -b '1' --along --blong '3' -- 'a b'
$1 is -a
a's choosen
$1 is -c
c's arg:'2'
$1 is -b
b's arg:'1'
$1 is --along
a's choosen
$1 is --blong
b's arg:'3'
$1 is --
remaining args
-->'a
-->b'可见
getopt
将
-ac2 -b 1 --along --blong 3 'a b'
处理为
-a -c '2' -b '1' --along --blong '3' -- 'a b'
而
ac2 -b 1 --along --blong 3 'a b'
将会被处理为
-a -c '' -b '1' --along --blong '3' -- 'a b'
即可选参数后将会有空字符出现,所以对可选参数的处理中又使用了一层case -
使用注意
两者都不会自带面对同样含义选项卡时只执行一次的功能,
比如-h
和--help
这里会执行两次
不知道别人怎么解决的