I have a script that runs every 15 minutes but sometimes if the box is busy it hangs and the next process will start before the first one is finished creating a snowball effect. How can I add a couple lines to the bash script to check to see if something is running first before starting?
我有一个每15分钟运行一次的脚本,但有时如果盒子忙,它会挂起,下一个过程将在第一个完成创建雪球效果之前开始。如何在bash脚本中添加几行以在启动之前检查某些内容是否先运行?
9 个解决方案
#1
In lieu of pidfiles, as long as your script has a uniquely identifiable name you can do something like this:
代替pidfiles,只要您的脚本具有唯一可识别的名称,您就可以执行以下操作:
#!/bin/bash
COMMAND=$0
# exit if I am already running
RUNNING=`ps --no-headers -C${COMMAND} | wc -l`
if [ ${RUNNING} -gt 1 ]; then
echo "Previous ${COMMAND} is still running."
exit 1
fi
... rest of script ...
#2
You can use pidof -x
if you know the process name, or kill -0
if you know the PID.
如果您知道进程名称,则可以使用pidof -x;如果知道PID,则可以使用kill -0。
Example:
if pidof -x vim > /dev/null
then
echo "Vim already running"
exit 1
fi
#3
Why don't set a lock file ?
为什么不设置锁文件?
Something like
yourapp.lock
Just remove it when you process is finished, and check for it before to launch it.
只需在处理完成后将其删除,并在启动之前检查它。
It could be done using
它可以使用
if [ -f yourapp.lock ]; then
echo "The process is already launched, please wait..."
fi
#4
pgrep -f yourscript >/dev/null && exit
#5
This is how I do it in one of my cron jobs
这就是我在我的一个cron工作中的表现
lockfile=~/myproc.lock
minutes=60
if [ -f "$lockfile" ]
then
filestr=`find $lockfile -mmin +$minutes -print`
if [ "$filestr" = "" ]; then
echo "Lockfile is not older than $minutes minutes! Another $0 running. Exiting ..."
exit 1
else
echo "Lockfile is older than $minutes minutes, ignoring it!"
rm $lockfile
fi
fi
echo "Creating lockfile $lockfile"
touch $lockfile
and delete the lock file at the end of the script
并删除脚本末尾的锁定文件
echo "Removing lock $lockfile ..."
rm $lockfile
#6
For a method that does not suffer from parsing bugs and race conditions, check out:
对于不解析错误和竞争条件的方法,请查看:
- BashFAQ/045 - How can I ensure that only one instance of a script is running at a time (mutual exclusion)?
BashFAQ / 045 - 如何确保一次只运行一个脚本实例(互斥)?
#7
I had recently the same question and found from above that kill -0 is best for my case:
我最近有同样的问题,从上面发现kill -0最适合我的情况:
echo "Starting process..."
run-process > $OUTPUT &
pid=$!
echo "Process started pid=$pid"
while true; do
kill -0 $pid 2> /dev/null || { echo "Process exit detected"; break; }
sleep 1
done
echo "Done."
#8
To expand on what @bgy says, the safe atomic way to create a lock file if it doesn't exist yet, and fail if it doesn't, is to create a temp file, then hard link it to the standard lock file. This protects against another process creating the file in between you testing for it and you creating it.
要扩展@bgy所说的内容,创建锁定文件的安全原子方法(如果它尚不存在,如果不存在则失败)是创建临时文件,然后将其硬链接到标准锁定文件。这可以防止在您测试文件和创建文件之间创建文件的另一个进程。
Here is the lock file code from my hourly backup script:
这是我的每小时备份脚本中的锁定文件代码:
echo $$ > /tmp/lock.$$
if ! ln /tmp/lock.$$ /tmp/lock ; then
echo "previous backup in process"
rm /tmp/lock.$$
exit
fi
Don't forget to delete both the lock file and the temp file when you're done, even if you exit early through an error.
完成后不要忘记删除锁定文件和临时文件,即使您因错误提前退出也是如此。
#9
Use this script:
使用此脚本:
FILE="/tmp/my_file"
if [ -f "$FILE" ]; then
echo "Still running"
exit
fi
trap EXIT "rm -f $FILE"
touch $FILE
...script here...
This script will create a file and remove it on exit.
此脚本将创建一个文件并在退出时将其删除。
#1
In lieu of pidfiles, as long as your script has a uniquely identifiable name you can do something like this:
代替pidfiles,只要您的脚本具有唯一可识别的名称,您就可以执行以下操作:
#!/bin/bash
COMMAND=$0
# exit if I am already running
RUNNING=`ps --no-headers -C${COMMAND} | wc -l`
if [ ${RUNNING} -gt 1 ]; then
echo "Previous ${COMMAND} is still running."
exit 1
fi
... rest of script ...
#2
You can use pidof -x
if you know the process name, or kill -0
if you know the PID.
如果您知道进程名称,则可以使用pidof -x;如果知道PID,则可以使用kill -0。
Example:
if pidof -x vim > /dev/null
then
echo "Vim already running"
exit 1
fi
#3
Why don't set a lock file ?
为什么不设置锁文件?
Something like
yourapp.lock
Just remove it when you process is finished, and check for it before to launch it.
只需在处理完成后将其删除,并在启动之前检查它。
It could be done using
它可以使用
if [ -f yourapp.lock ]; then
echo "The process is already launched, please wait..."
fi
#4
pgrep -f yourscript >/dev/null && exit
#5
This is how I do it in one of my cron jobs
这就是我在我的一个cron工作中的表现
lockfile=~/myproc.lock
minutes=60
if [ -f "$lockfile" ]
then
filestr=`find $lockfile -mmin +$minutes -print`
if [ "$filestr" = "" ]; then
echo "Lockfile is not older than $minutes minutes! Another $0 running. Exiting ..."
exit 1
else
echo "Lockfile is older than $minutes minutes, ignoring it!"
rm $lockfile
fi
fi
echo "Creating lockfile $lockfile"
touch $lockfile
and delete the lock file at the end of the script
并删除脚本末尾的锁定文件
echo "Removing lock $lockfile ..."
rm $lockfile
#6
For a method that does not suffer from parsing bugs and race conditions, check out:
对于不解析错误和竞争条件的方法,请查看:
- BashFAQ/045 - How can I ensure that only one instance of a script is running at a time (mutual exclusion)?
BashFAQ / 045 - 如何确保一次只运行一个脚本实例(互斥)?
#7
I had recently the same question and found from above that kill -0 is best for my case:
我最近有同样的问题,从上面发现kill -0最适合我的情况:
echo "Starting process..."
run-process > $OUTPUT &
pid=$!
echo "Process started pid=$pid"
while true; do
kill -0 $pid 2> /dev/null || { echo "Process exit detected"; break; }
sleep 1
done
echo "Done."
#8
To expand on what @bgy says, the safe atomic way to create a lock file if it doesn't exist yet, and fail if it doesn't, is to create a temp file, then hard link it to the standard lock file. This protects against another process creating the file in between you testing for it and you creating it.
要扩展@bgy所说的内容,创建锁定文件的安全原子方法(如果它尚不存在,如果不存在则失败)是创建临时文件,然后将其硬链接到标准锁定文件。这可以防止在您测试文件和创建文件之间创建文件的另一个进程。
Here is the lock file code from my hourly backup script:
这是我的每小时备份脚本中的锁定文件代码:
echo $$ > /tmp/lock.$$
if ! ln /tmp/lock.$$ /tmp/lock ; then
echo "previous backup in process"
rm /tmp/lock.$$
exit
fi
Don't forget to delete both the lock file and the temp file when you're done, even if you exit early through an error.
完成后不要忘记删除锁定文件和临时文件,即使您因错误提前退出也是如此。
#9
Use this script:
使用此脚本:
FILE="/tmp/my_file"
if [ -f "$FILE" ]; then
echo "Still running"
exit
fi
trap EXIT "rm -f $FILE"
touch $FILE
...script here...
This script will create a file and remove it on exit.
此脚本将创建一个文件并在退出时将其删除。