shell 中的参数传递
在执行 shell 脚本的时候,可以向脚本传递参数,shell 中的方法执行也可以传参,另外还包含了一些复杂的情况。
这块一直很模糊,用到的时候才去查,这里做个总结。
依次获取
$0,$1,$2...
在使用 sh script.sh "hello" "world"
的时候,可以使用 $0,$1,\$2...
去依次获取脚本命令行传入的参数。
$1
得到的是 hello
,$2
得到的是 world
,依次类推。
可以使用 $@
来获取所有参数:
bash
1for item in "$@"
2do
3 echo $item
4done
此种方法也可用于函数中获取参数。
获取脚本路径
$0
获取到的是脚本路径以及脚本名,比如:
sh a.sh
,$0
是 a.sh
sh a/b.sh
,$0
是 a/b.sh
在获取当前脚本目录的时候很有用,因为 shell 中的路径是相对于 cwd 的,如果在脚本中使用相对路径,可能会发生不可知的问题,所以我个人习惯先定位到脚本所在目录,或者项目根目录。
shell
1# 脚本所在目录
2
3SCRIPT_DIR=$(cd `dirname $0`; pwd)
使用 getopts
使用上面的方式对于参数少的情况下挺方便,但如果参数多,就可能弄混,可读性不好。另外如果脚本有修改也容易造成错误,毕竟对于参数顺序有依赖。
另一种优雅的方式是使用 getopts
,直接看一个例子:
bash
1#!/bin/bash
2
3function Usage() {
4 cat << EOF
5--- Usage start ---
6-n name
7-a age
8--- Usage end ---
9EOF
10}
11
12while getopts ":n:a:" opt
13do
14 case "$opt" in
15 n)
16 echo "name is $OPTARG"
17 ;;
18 a)
19 echo "age is $OPTARG"
20 ;;
21 ?)
22 Usage
23 exit 1
24 ;;
25 esac
26done
27
28# 调用:
29sh xxx.sh -n tom -a 233
30
getopts
用来分析位置参数,格式为:
bash
getopts optstring optname
optstring
包含需要被识别的选项字符。第一个 :
表示忽略错误参数,如果其中的字符后面跟着一个冒号,表明该字符选项需要一个选项值,其字符选项需要以空格分隔,一般与 while 一起用。
getopts
每次被调用时,它会将下一个选项字符放置到变量 optname
中,选项如果有对应的值,会放在变量 $OPTARG
里面,$OPTIND
表示参数索引,从 1 开始。
环境变量
使用环境变量传参,也是一种常见的方式。
shell
1# 当前脚本、以及所有子shell,都可以访问 $ABC
2export ABC="DEF"
3sh balabala.sh
4
5# or
6
7# 在该子shell中,可以访问 $ABC
8ABC="DEF" sh balabala.sh