我不太喜欢shell编程,感觉能用python就用python了。不过有时候shell脚本确实很方便,比如:
[ `pgrep -f 'autossh -M 20033'` ] || autossh -M 20033 -gnfNTR 40221:localhost:22 pi
该命令就能检测当前autossh的某个连接是否存在,没有的话则启动,这样做的目的是保持持续连接,做稳定的反向代理。
其实一开始的命令是这样的:
[ `pgrep -f 'autossh -M 20033 -gnfNTR 40221:localhost:22 pi'` ] || autossh -M 20033 -gnfNTR 40221:localhost:22 pi
但是这样导致前面的检测总是为false,因此会执行后面的命令,报错:
bind on 127.0.0.1:20034: Address already in use
仔细排查了下:
@hp:~/bin$ ps aux|grep autossh
dww 1294 0.0 0.0 4528 1724 ? Ss 10月18 0:00 /usr/lib/autossh/autossh -M 20033 -gnNTR 40221:localhost:22 pi
这里运行的时候-gnNTR后面有俩空格,而我命令中是一个空格。pgrep -f 非常严格,多了个空格就不行:
dww@hp:~/bin$ [ `pgrep -f 'autossh -M 20033 -gnNTR 40221:localhost:22 pi'` ] || echo 'hi'
hi
dww@hp:~/bin$ [ `pgrep -f 'autossh -M 20033 -gnNTR 40221:localhost:22 pi'` ] || echo 'hi'
dww@hp:~/bin$
你看,第一条空格仅有一个,则pgrep认为没有该命令,因此执行了后面的;第二条是两个空格,pgrep -f 认为是有该进程,所以没输出hi。所以这个问题也很奇怪,不知道这个autossh运行中为什么多了个空格,我shell了解也不多,然后就改成本文第一行那种命令了,仅仅检测到守护进程20033就行,不管后面的参数了。
我的博客不是像别人那种很全的学习,基本都是针对问题解决,都是小例子。
实际上这样的命令我也不会写,还是借来的,在此问题上,顺便学习下shell的几个运算符,主要就是命令中用的“ [] ”和“ || ”。
pgrep -f 得到的是进程id,如:
dww@hp:~/bin$ pgrep -f 'autossh -M 20033 -gnNTR 40221:localhost:22 pi'
1294
然后用反单引号进行变量替换,接着是方括号的,方括号就是测试,在命令行里test expr和[ expr ]的效果相同。从前面的例子也能看出,和 || 配合起来,前面的命令执行不成功就执行后面的,前面的执行成功则忽略后面的。
不是很想学shell,感觉不太习惯,就此结束。