写了一个很简单的脚本,用于统计memcache进程的数量:
#!/bin/bash
echo `ps aux | grep memcache | grep -v grep | wc -l`
然而在执行时却遇到了问题:
[work@ oss_memcache_status]$ pwd
/home/work/cdn/monitor/ocelot-scripts/oss_memcache_status
[work@ oss_memcache_status]$ ./run.sh
1
[work@ oss_memcache_status]$ ../oss_memcache_status/run.sh
3
这个原因是因为我们在执行shell脚本时,会通过子进程的方式来执行,而子进程的执行路径字段为:../oss_memcache_status/run.sh
,会被grep过滤器留下,因此统计数量比预期要多1个。
解决方案为grep -v bash
。
执行shell脚本的方式
我们有三种常用的方式执行shell脚本:
- source run.sh: 会在当前进程下执行脚本,执行时的变量会保存下来。
- . run.sh: 和source方法基本一样,区别在于source不是POSIX要求的。
- ./run.sh: 如果脚本以
#!/bin/bash
开头,会在单独的子进程中执行,执行完毕后变量不保存。否则和source一样。
因此,在上面的脚本中,我们在执行时,因为是以#!/bin/bash
开头,会在子进程中执行,我们改动一下脚本看都是哪些进程:
#!/bin/bash
echo `ps aux | grep memcache | grep -v grep`
执行:
work 24414 0.0 0.0 108116 1276 pts/0 S+ 15:31 0:00 /bin/bash ../oss_memcache_status/run.sh
work 24415 0.0 0.0 108116 612 pts/0 S+ 15:31 0:00 /bin/bash ../oss_memcache_status/run.sh
work 30558 0.0 0.0 371236 47096 ? Ssl 2016 15:14 /usr/local/bin/memcached -d -m 256 -u nobody -l localhost -p 11211
我们通过结果,可以看出来,第一个进程和第二个进程的父进程相同,他们都属于当前终端启动的进程。前两个分别为执行run脚本的进程和调起的子进程(这两个什么区别,我也不太清楚),第三个为真正的进程。
防止进程数量增多
解决方案:
- 删除脚本头部
#!/bin/bash
- 增加过滤:
grep -v bash
- 改变调用方式:source run.sh
参考资料
- 执行 shell 脚本时,「source」、「. 」和「./」的区别:https://hoxis.github.io/linux…