编写 Linux Shell 脚本处理命令行参数
如果不会用 Linux 文本编辑器 nano / vim 等,请自行了解相关用法。
如果是新建文件,默认应该没有执行权限,需要 chmod +x 文件名 添加权限。
原生#
$0 / $1 / $2 / $3 ... $##
新建或编辑 test_args.sh,输入以下内容并保存:
|  |  | 
附带参数运行该脚本:
$ ./test_args.sh apple banana candy
执行的目标: ./test_args.sh
第一个参数为:apple
第二个参数为:banana
第三个参数为:candy
参数个数为:3
$@ / $*#
新建或编辑 test_args.sh,输入以下内容并保存:
|  |  | 
附带参数运行该脚本:
$ ./test_args.sh apple banana candy
全部参数组成一个数组:[apple banana candy]
apple
banana
candy
全部参数组成一个字符串: "apple banana candy"
apple banana candy
$$ / $! / $?#
新建或编辑 test_args.sh,输入以下内容并保存:
|  |  | 
附带参数运行该脚本:
$ ./test_args.sh
此脚本运行的当前进程 pid: 4255
后台运行的最后一个进程的 pid: 4256
上一条命令是否执行成功: 0 (0=成功 非0=失败)
$_#
新建或编辑 test_args.sh,输入以下内容并保存:
|  |  | 
附带参数运行该脚本:
$ ./test_args.sh
此脚本文件名: /root/era_games_data/./test_args.sh
maybe next time
上一条命令(echo)的最后一个参数: time
上一条命令(let)的最后一个参数: "foo=123"
123
上一条命令(echo)的最后一个参数: 123(此处直接取其值 而不是原样打印变量名)
$-#
新建或编辑 test_args.sh,输入以下内容并保存:
|  |  | 
附带参数运行该脚本:
$ ./test_args.sh
打印当前 shell 的选项: hB
- H-- histexpand:已启用 历史记录扩展(History Expansion)
- m-- monitor:已启用 作业控制(Job Control)
- h-- hashall:允许记住命令以便之后查找并再次运行
- B-- braceexpand:已启用 花括号扩展(Brace Expansion)
- i-- interactive:当前 shell 是可交互的
功能稍弱,用法也更简单 - getopts#
用法说明#
- 只能在 shell 脚本中使用,不能在命令行中单独使用
- 只支持形如 -p的短格式,不支持形如--port的长格式
- 要么包含具体的参数值(如 -p 80),要么不包含(如-h),只能二选一
 (注意这里只是随便举的例,你完全可以设定-p不包含参数值,而-h包含)
- 如果包含具体的参数值:- 既可以用空格隔开(如 -p 80),也可以紧接其后(如-p80)
- 只提供了参数却没有提供具体值时(如 -p)会直接报错
 
- 既可以用空格隔开(如 
实际举例#
新建或编辑 test_args.sh,输入以下内容并保存:
|  |  | 
这里
getopts的参数格式为i:p:h,可以分割为i:+p:+h。
带:的意思是「需要指定具体的参数值」,没带:的就不用。
测试用例#
运行该脚本:
$ ./test_args.sh -h
参数用法:
    -i    指定 IP
    -p    指定端口
    -h    显示帮助信息
$ ./test_args.sh -i 127.0.0.1 -p 80
ip:   127.0.0.1
port: 80
$ ./test_args.sh -i192.168.1.1 -p80
ip:   192.168.1.1
port: 80
功能更强,用法也更复杂 - getopt#
没有写反,
getopt(不带s)就是比带s的getopts功能更多、更复杂。
用法说明#
- 既可以在 shell 脚本中使用,又能在命令行中单独使用
- 既支持形如 -p的短格式,又支持形如--port的长格式
- 可以同时兼容包含具体的参数值(如 -p 80),以及不包含(如-p)的情况
- 如果包含具体的参数值:- 形如 -p的短格式:
 既可以用空格隔开(如-p 80),也可以紧接其后(如-p80)
- 形如 --port的长格式:
 可以用空格(如--port 80)或等号(如--port=80)隔开
 
- 形如 
实际举例#
新建或编辑 test_args.sh,输入以下内容并保存:
|  |  | 
至于
getopt的参数格式,首先getopt本身有三个参数:
-o/--options:支持形如-p的短格式
比如i:p::h,可以分割为i:+p::+h
比getopts多出一个带::的格式,意思是可选是否指定具体值
-l/--long:支持形如--port的长格式
冒号:的意义同短格式,不过多个参数之间需要用逗号,分开
比如ip:,port::,help,可以分割为ip:,port::,help
-n/-name:指定解析错误时提示的脚本名- 更多参数用法详见
getopt -h
测试用例#
运行该脚本:
$ ./test_args.sh -h
参数用法:
    -i, --ip
            指定 IP
    -p, --port
            指定端口
    -h, --help
            显示帮助信息
$ ./test_args.sh -i127.0.0.1 -p80 input output
ip:   127.0.0.1
port: 80
剩余未处理的参数: input
剩余未处理的参数: output
$ ./test_args.sh -i 192.168.1.1 -p 80 input output
# 由于port可以不指定具体值 所以后面的80会被当作孤立的另外一个参数
ip:   192.168.1.1
port: 没有指定具体值(此时可以另行处理,比如默认为80)
剩余未处理的参数: 80
剩余未处理的参数: input
剩余未处理的参数: output
$ ./test_args.sh --ip=0.0.0.0 --port=8080 input output
ip:   0.0.0.0
port: 8080
剩余未处理的参数: input
剩余未处理的参数: output
$ ./test_args.sh --ip 0.0.0.0 --port 8080 input output
# 由于port可以不指定具体值 所以后面的8080会被当作孤立的另外一个参数
ip:   0.0.0.0
port: 没有指定具体值(此时可以另行处理,比如默认为80)
剩余未处理的参数: 8080
剩余未处理的参数: input
剩余未处理的参数: output