SpringShell 提供了@ShellOption注解用于指定参数的帮助信息, 或对特殊参数进行处理.
1. 传参方式
- SpringShell 命令调用时, 有两种传参方式, 一种是位置参数, 一种是命名参数. 虽然说也可以混合使用, 但是笔者不建议混合使用.
- SpringShell 命令默认参数分隔符为多个空格, 如果要传入参数包含空格, 需要使用引号包裹.
- SpringShell 参数严格匹配参数个数, 除非定义命令时指定的是可变参数
// 定义命令时: 第一个参数为username, 第二个参数为password
@ShellMethod("check username and password")
public String auth(String username, String password) {
return "username:" + username + ", password:" + password;
}
1.1 位置参数
位置参数和参数顺序有关, 顺序为方法定义时参数排列顺序.
# 第一个参数root 会赋值给username, 第二个参数会赋值给pasword
shell:>auth root 123456
username:root, password:123456
shell:>auth 123456 root
username:123456, password:root
1.2 命名参数
- 命名参数和参数位置无关, 默认需要使用"--"指定参数名称, 可通过在定义命令时@ShellMethod的prefix 属性更改参数前缀.
- 对于布尔类型参数, 只能使用命名参数方式来赋值, 但是不能指定命名参数的值.
# 传参顺序不同, 毫无影响.
shell:>auth --password root --username root
username:root, password:root
shell:>auth --password 123456 --username root
username:root, password:123456
2. 特殊类型参数处理
2.1 一个参数接收多个值
对于数组, 集合等类型变量, 需要使用@ShellOption的arity属性明确指定接收的参数个数, 否则不能正确执行命令.
@ShellMethod("add three numbers")
public String multiSum(@ShellOption(arity = 3) int[] numbers) {
int sum = numbers[0] + numbers[1] +numbers[2];
return numbers[0] + "+" + numbers[1] + "+" + numbers[2] + "=" + sum;
}
@ShellMethod("multiply three numbers")
public String multiply(@ShellOption(arity = 3) List<Integer> numbers) {
int result = numbers.get(0) * numbers.get(1) * numbers.get(2);
return numbers.get(0) + "x" + numbers.get(1) + "x" + numbers.get(2) + "=" + result;
}
# 命名参数调用方式
shell:>multi-sum --numbers 1 2 3
1+2+3=6
# 位置参数调用方式
shell:>multiply 2 3 4
2x3x4=24
2.2 布尔类型参数
对于布尔类型参数, 相当于设置了arity=0, 只能通过命名参数指定名称来赋值, 且命名参数不能赋值. 赋值会出现异常.
@ShellMethod("shutdown")
public String shutdown(boolean force, int seconds) {
return "force: " + force + ", seconds:" + seconds;
}
# 指定命名参数即为true, 无须赋值. 赋值会出现异常
sshell:>shutdown 30 --force
force: true, seconds:30
shell:>shutdown --force 30
force: true, seconds:30
# 不指定命名参数, 即为false
shell:>shutdown 30
force: false, seconds:30
2.3 参数引号处理
- SpringShell 命令接收参数时, 默认以多个空格作为参数分隔符, 如果参数包含空格的话, 会被视为多个参数.
- 对于包含空格的参数, 可以使用引号进行包裹.
- 若想输出引号, 可以采用单引号双引号相互包裹, 或使用转移字符. 单引号和双引号完全等价, 不存在可转义不可转义差别.
# 使用引号包裹带空格字符串
shell:>echo "hello world"
hello world
# 单引号包裹双引号, 输出双引号
shell:>echo '"hello world"'
"hello world"
# 双引号包裹单引号, 输出单引号
shell:>echo "'hello world'"
'hello world'
# 双引号内转义字符, 输出双引号
shell:>echo "\"hello world\""
"hello world"
# 单引号内转义字符, 输出单引号
shell:>echo '\'hello world\''
'hello world'
2.4 参数设定默认值
当一个命令可接收参数也可不接收参数时, 可以通过指定参数默认值来解决. 比如说实现linux shell中的echo命令, 当没有参数时输出空行, 当有参数时输出参数.
@ShellMethod("print line")
public String echo(@ShellOption(defaultValue = "") String line) {
return line;
}
# 无参调用
shell:>echo
# 有参调用, 包含空格的参数需要使用引号包裹
shell:>echo "hello world"
hello world
2.5 参数设定帮助信息
可以通过help 属性来指定参数的帮助信息, 使用help 命令查看参数时, 可以查看设定的帮助信息.
@ShellMethod("check username and password")
public String auth(
@ShellOption(help = "用户名") String username,
@ShellOption(help = "密码") String password) {
return "username:" + username + ", password:" + password;
}
shell:>help auth
NAME
auth - check username and password
SYNOPSYS
auth [--username] string [--password] string
OPTIONS
--username string
用户名
[Mandatory]
--password string
密码
[Mandatory]