启动脚本编写
时间:2010-05-13 来源:zyd_cu
#!/bin/bash
exepath=/home/ydzhang/dnfs
prog=dnfs-server
export status=0 # 0 denotes stopped, 1 denotes started.
killproc()
{
ps -e | grep $1 | {
while read pid tty time cmd
do
echo "Killing $cmd(pid = $pid) ..."
kill -9 $pid
done
}
}
start()
{
echo starting $prog ...
if [ $status -eq 0 ]
then
$exepath/$prog & # run program in background
status=1
fi
rq_status
}
stop()
{
echo $status
echo stopping $prog ...
if [ $status -eq 1 ]
then
killproc $prog
status=0
fi
rq_status
}
restart()
{
stop
start
}
rq_status()
{
if [ $status -eq 0 ]
then
echo $prog is stopped
else
echo $prog is started
fi
}
gt_status()
{
ps -e | grep $prog | {
while read pid tty time cmd
do
if [ $cmd = $prog ]
then
status=1
break
fi
done
}
}
gt_status
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
rq_status
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
esac
以上脚本用于启动,关闭,重新启动某个程序,类似于/etc/init.d中的脚本。
最开始没有使用gt_status,即在执行脚本前检查该程序的进程是否存在,每次stop的时候都会出问题,因脚本执行完毕后,status的赋值生效,但stop是重新执行一次脚本,故status的默认值为0,故stop什么都不做。
于是加上gt_status,检查程序是否已经运行,问题依然存在,即使已有进程在运行,status的值仍没有被设置为1。 考虑到肯定是跟变量的性质有关,到网上查了一下,发现由于gt_status中使用了管道操作,while语句的操作都是在子shell中完成,此时的status为子shell下的新变量,而不是脚本开始处的status变量;即使export变量status,子shell对status的修改对父shell也不可见。
父shell与子shell间的变量遵守以下原则:
1. 没有导出的变量是局部变量,子shell是看不到的。
2. 导出变量列表被赋值给子shell,子shell可以修改和存取它,但是这种修改对父shell不可见。
3. 导出变量列表的上述特性对于直接产生的子shell生效,对于由子shell产生的后继子shell也是如此。
4. export可以在变量赋值之后用,也可以在变量赋值之前用。
对于本例中的需求,可通过将ps –e | grep $prog的结果先定向到一个临时文件中,然后从临时文件中读取,判断cmd是否为$prog,然后设置status的值,此时的值由父shell设置,故接下来的case语句中能读到case的新值。
求教更好的解决方法,不甚感激。