#!/bin/bash
#ulimit -c unlimited
export PS4='+{$LINENO($(date +"%F %T")):${FUNCNAME[0]}} '
full_path=$(readlink -f $0)
#cd $(dirname $full_path)
#exec 1>${full_path%.*}.log
exec 2>${full_path%.*}.err
set -x
usage() {
printf \
"Usage: %s <pid|pid_file> <start_cmd|start_script>\n\n \
pid|pid_file process pid or the pid file containing the pid of process to be supervised\n \
start_cmd|start_script start commands or start script if process dead\n \
\n" $1
exit 1
}
if [ $# -lt 2 ]; then
usage $0
fi
pid_way=$1
if [ "" != "${pid_way//[0-9]}" -a -s "$pid_way" ]; then
pid_file=$(readlink -f $pid_way)
else
pid_id=$pid_way
pinfo=($(ps -eo uid,pid,args | awk -v pid=$pid_id '{if($2==pid)print $0}'))
puid=${pinfo[0]}
pname=${pinfo[2]}
if [ "" == "$puid" -o "" == "$pname" ]; then
echo "Couldn't find the process with the pid $pid_id"
exit 2
fi
fi
cmd=($2)
if [ -s "${cmd[0]}" ]; then
start_way=$(readlink -f ${cmd[0]})
for ((i=1; i<${#cmd[@]}; ++i)); do
start_way="$start_way ""${cmd[$i]}"
done
shift 2
start_way="$start_way ""$@"
else
shift 1
start_way="$@"
fi
while true; do
if [ "" != "$pid_id" ]; then
pid=$pid_id
else
pid=$(cat $pid_file)
fi
if [ "" != "$pid" ]; then
if ! kill -0 $pid; then
now=$(date +%s)
$start_way
#sleep 60
if [ "" != "$pid_id" ]; then
tm_fields_num=$(ps -eo lstart | tail -1 | awk '{print NF}')
find_new_process=0
pid_id_bak=()
while read line; do
pstarttime=$(date -d "${line#* }" +%s)
if [ "$pstarttime" -ge "$now" ]; then
pid_id_tmp=${line%% *}
pinfo_new=($(ps -eo uid,pid,args | awk -v pid=$pid_id_tmp '{if($2==pid)print $0}'))
if [ "0" == "${#pinfo_new[@]}" ]; then
continue
fi
diff_fields_num=0
for ((i=3; i<(${#pinfo[@]} > ${#pinfo_new[@]} ? ${#pinfo[@]} : ${#pinfo_new[@]}); ++i)); do
if [ "${pinfo[$i]}" != "${pinfo_new[$i]}" ]; then
((++diff_fields_num))
fi
done
if [ "0" -eq "$diff_fields_num" ]; then
pid_id=$pid_id_tmp
if [ "$((++find_new_process))" -gt "1" ]; then
exit 1
fi
else
pid_id_bak[$diff_fields_num]=$pid_id_tmp
fi
fi
done < <(ps -eo uid,pid,lstart,args | awk -v puid=$puid -v pname=$pname -v tfn=$tm_fields_num '{if($1==puid && $(3+tfn)==pname){printf "%d ", $2; for(i=3;i<3+tfn;++i) printf "%s ", $i; printf "\n";}}')
if [ "0" == "$find_new_process" ]; then
pid_id=${pid_id_bak[@]}
pid_id=${pid_id%% *}
fi
else
tm_new_pid_file=$(date -d "$(stat $pid_file | grep ^Modify: | sed 's#Modify:##')" +%s)
if [ "$tm_new_pid_file" -lt "$now" ]; then
exit 2
fi
fi
fi
fi
#sleep 1
if [ "$(ls -l ${full_path%.*}.err | awk '{print $5}')" -ge $((1024 * 1024 * 1024)) ]; then
set +x
exec 2>/dev/null
cp ${full_path%.*}.err ${full_path%.*}.err.last
rm -f ${full_path%.*}.err
exec 2>${full_path%.*}.err
set -x
fi
done