How to control a script is not already running?

有些话、适合烂在心里 提交于 2019-12-12 01:59:13

问题


I have a shell script executed by cron and I want to control that it's not already running. This is my control test:

set -A processes
ps -elf | grep -v grep | grep -E "/bin/ksh.+scriptName" | while read line ;do processes[${#processes[@]}]="$line";done
if [ ${#processes[@]} -gt 1 ]; then
    for i in {0..$((${#processes[@]}-1))}; do echo "${processes[$i]}"; done
    exit 1
fi

The problem is that this control returns sometimes 2 processes (of itself):

F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD

0 S user 12486 12485 0 85 0 - 2469 - 15:30 ? 00:00:00 /bin/ksh /path/scriptName ARG1

1 D user 12503 12486 0 85 0 - 2469 get_wr 15:30 ? 00:00:00 /bin/ksh /path/scriptName ARG1

I do not understand why it happens sometimes...How to resolve this problem? How to control a script is not already running (without "flag"/semaphore file)? Thanks for your help!


回答1:


Two options:

  1. Allow the job to start, but have scriptName script check if it is already running and kill itself.
  2. Switch to a more sophisticated job scheduler such as http://nerds.airbnb.com/introducing-chronos/



回答2:


Using pipes can spawn subprocesses, which show up in the process table. Limit the "ps" output and it becomes easier to parse:

ps -eo pid,ppid,args | grep -vw $$ | grep -qE "[0-9]+ /bin/ksh $0" && echo "ALREADY RUNNING"

This removes anything from the list that has the current PID ($$) as its PID or Parent PID, and then matches the scriptname as a pattern. You really don't even need the "[0-9]+" in the pattern, since the first grep excludes all of your child processes (otherwise the "grep" itself would match).



来源:https://stackoverflow.com/questions/25254017/how-to-control-a-script-is-not-already-running

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!