今天上午,同事叫我帮他看下他正在写的脚本到底哪里出了问题,执行总是达不到预期功能。于是ssh连过去看能否发现问题,经过多次Debug定位与排除,问题终于得到解决。
同事在网上down了一个脚本菜单模板,想把我们已经存在的功能脚本整合到一起,做成多功能的Linux运维工具。目前已经添加了挺多功能,而早上才添加的一个抓取高占用CPU的Java线程功能时出现了无法出现交互界面的问题,而单独去执行这个子脚本又是正常的。
我将这个案子拿到手之后,第一件事就是打开了主菜单,分析了一下菜单功能原理和大致结构。通过断点定位法我找到问题出现的位置:
这是主菜单调用子脚本关键代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
***** 以上略*****
*) run=`awk -F "$MENUCHAR" 'NR=="'$input'"{print $2}' $1`
if [ "`echo $run | awk -F "." '{print $NF}'`" = "$MENUTYPE" ]
then
if [ ! -f $MENUPATH/$run ]
then
echo "ERR-0: 菜單檔 $MENUPATH/$run 不存在..."
Enter
else
echo $run #我调试时新加入的,用于输出具体变量信息
Menu $MENUPATH/$run
fi
else
eval $run
Enter
fi
;;
*****以下略*****
|
我在子脚本调用的前面加入了 echo $run,用来确定脚本是否运行到了此处、变量内容是否是我们所预期的。
执行后,打印结果如下:
|
***略***
menu/scripts/jtgrep &
任意键继续...
|
看到第一行后面的 &符号,再打开如下的子菜单查看,立马得出结论:原来是同事编写的子菜单格式兼容性存在问题,他在每个调用子脚本语句后面加了后台运行标识符 &:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
查看此伺服器的IP地址%menu/scripts/ip &
查看此伺服器的型號及Serial Number%menu/scripts/productname &
查看此伺服器的操作系統版本及內核信息%menu/scripts/os &
查看此伺服器的網卡信息%menu/scripts/eth &
查看此伺服器的網卡流量%menu/scripts/netflood &
查看此伺服器的MAC地址%menu/scripts/hwaddr &
查看此伺服器的內存%menu/scripts/mem &
查看此伺服器的CPU%menu/scripts/cpu &
查看此伺服器的硬碟及陣列信息%menu/scripts/disk &
查看系統當前的平均負載%menu/scripts/uptime &
查看系統當前用戶登入數%menu/scripts/users &
查看系統線上運行時間%menu/scripts/onlinetime &
查看系統的主機名%menu/scripts/hostname &
查看系統最大文件句柄數%menu/scripts/ulimit &
查看系統運行的進程信息%menu/scripts/task &
抓取JAVA佔用CPU高的線程%menu/scripts/jtgrep &
|
有了这个&标识符,调用的脚本将置于后台执行,之所以前15项都能正常,唯独第16项有问题,是因为这项功能存在read交互语句,如第9、13行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/bin/bash
#Program:
#抓取JAVA佔用CPU高的線程
#2014/02/24
echo ""
echo "系統目前運行的JAVA線程PID為:"
ps aux | grep "java" | grep -v grep | sed 's/pts.*classpath//g' | awk '{print $2,$7}'
read -p "請輸入你要查詢的JAVA線程PID的值:" java_pid
top -Hp $java_pid -d 1 -n 1
echo "請記住上面佔用CPU資源較大的幾個JAVA線程的PID"
jstack $java_pid > menu/reports/jstack.log
read -p "請輸入佔用CPU資源較大的其中一個JAVA線程的PID:" top_pid
nid=`python -c "print hex($top_pid)"`
grep -i $nid menu/reports/jstack.log
|
将其置于后台运行,read -p的显示根本都看不到,焉能交互?! 终于抓到了“元凶”,就是置于后台运行的方式存在问题,它不兼容执行中需要交互的脚本。直接在vim中将&批量删除,保存后立竿见影!
正确的写法应该是:
|
抓取JAVA佔用CPU高的線程%menu/scripts/jtgrep
|
虽然就是这样一个小问题,但是200多行的主菜单脚本,还不是我写的,不仔细分析一下真的很难找到原因!空闲时间,我又回头观赏了一下这个工具菜单逻辑结构,感觉设计的不错,功能的添加非常灵活,值得借鉴,等完善之后,我会在博客记录分享一下!
全文完