短路运算符
cmd1 && cmd2
,先执行 cmd1,如果 cmd1 返回假,则将 cmd1 的返回值作为最终结果;如果 cmd1 返回真,则执行 cmd2,并将 cmd2 的返回值作为最终结果。cmd1 || cmd2
,先执行 cmd1,如果 cmd1 返回真,则将 cmd1 的返回值作为最终结果;如果 cmd1 返回假,则执行 cmd2,并将 cmd2 的返回值作为最终结果。! cmd
,逻辑非(取反),如果 cmd 返回真,则最终结果为假,如果 cmd 返回假,则最终结果为真。
小技巧:利用 &&
、||
来替代 if
(命令很短时,很有用)
condition && statement_if_true
condition || statement_if_false
condition && statement_if_true || statement_if_false
&&
和||
后只能跟一个语句,如果有多个,则第一个语句视为 statement 块,后面的视为正常语句;
如果需要将多条语句作为一个 statement,可以使用匿名函数:{ statement1; statement2; ...; }
。
另外就是第三种写法,需确保 statement_if_true
执行结果为 真,否则继续执行 statement_if_false
;
因为这是运算符结合性的问题,&&
和||
的优先级相同,而结合性则是从左往右,所以分两步执行:
condition && statement_if_true
,假设执行结果为result
result || statement_if_false
,根据result
,判定是否执行statement_if_false
追加运算符
string+=newstr
:追加 newstr 子串至 string 字符串末尾。array+=(element)
:追加 element 元素至 array 数组末尾。- shell 允许未定义
string
、array
时使用+=
追加运算符。
变量操作符
${variable:-default value}
:如果 variable 不存在或为空,则表达式返回 default value。${variable:=default value}
:如果 variable 不存在或为空,则将 default value 赋值给它。${variable:+alternate value}
:如果 variable 存在且不为空,则表达式返回 alternate value。${variable:?error message}
:如果 variable 不存在或为空,则表达式报告 error message 错误并结束脚本。
文件转换符
cmd $(<arg.dat)
:将$(<arg.dat)
替换为 arg.dat 的文件内容,作为 cmd 的命令行参数。cmd <(command)
:将<(command)
替换为一个可读文件的路径,此文件的内容是command
的 stdout。cmd >(command)
:将>(command)
替换为一个可写文件的路径,写入此文件的内容作为command
的 stdin。
EOF 用法
cmd <<EOF
,以单独的EOF
行结束:将输入的内容作为 cmd 的 stdin 数据,支持变量引用、命令替换。cmd <<'EOF'
,以单独的EOF
行结束:将输入的内容作为 cmd 的 stdin 数据,关闭变量引用、命令替换。cmd <<"EOF"
,以单独的EOF
行结束:将输入的内容作为 cmd 的 stdin 数据,关闭变量引用、命令替换。
$@
参数转发
如果你希望为一个命令添加自定义参数,可以考虑使用参数转发功能。比如 tomcat 的启动脚本 catalina.sh,原始脚本只提供 start|stop
等基本参数,我想添加一些自定义的参数,又不影响原有参数,可以吗?
当然,在你处理完自定义参数后,只需执行 catalina.sh "$@"
,表示将参数原模原样的传递给 catalina.sh,特别注意这个双引号,如果缺少,就不能处理参数中带空白符的情况了,也就失去了参数转发的意义。
没有双引号的情况:
showarg.sh
1
2
3
4
#!/bin/bash
for arg in "$@"; do
echo "$arg"
done
forward.sh
1
2
#!/bin/bash
exec ./showarg.sh $@
执行结果
1
2
3
4
5
6
7
8
9
10
11
$ ./showarg.sh '1 2 3' 'a b c'
1 2 3
a b c
$ ./forward.sh '1 2 3' 'a b c'
1
2
3
a
b
c
加了双引号的情况:
forward.sh
1
2
#!/bin/bash
exec ./showarg.sh "$@"
执行结果
1
2
3
4
5
6
7
$ ./showarg.sh '1 2 3' 'a b c'
1 2 3
a b c
$ ./forward.sh '1 2 3' 'a b c'
1 2 3
a b c