进程启动脚本编写【通用】

#!/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 的新值。

你可能感兴趣的:(脚本)