Как проверить bash script, если что-то запущено и выйти, если оно

У меня есть script, который запускается каждые 15 минут, но иногда, если ящик занят, он зависает, и следующий процесс запускается до того, как первый завершит создание эффекта снежного кома. Как я могу добавить пару строк в bash script, чтобы проверить, запускается ли что-то прежде, чем начать?

Ответ 1

Вместо pidfiles, если ваш script имеет уникально идентифицируемое имя, вы можете сделать что-то вроде этого:

#!/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

Вы можете использовать pidof -x, если знаете имя процесса, или kill -0, если вы знаете PID.

Пример:

if pidof -x vim > /dev/null
then
    echo "Vim already running"
    exit 1
fi

Ответ 3

Почему не устанавливать файл блокировки?

Что-то вроде

yourapp.lock

Просто удалите его, когда процесс завершится, и проверьте его, прежде чем запускать его.

Это можно сделать, используя

if [ -f yourapp.lock ]; then
echo "The process is already launched, please wait..."
fi

Ответ 4

pgrep -f yourscript >/dev/null && exit

Ответ 5

Вот как я делаю это в одном из моих заданий 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

и удалите файл блокировки в конце script

echo "Removing lock $lockfile ..."
rm $lockfile

Ответ 7

Недавно у меня был тот же вопрос и нашлось выше, что 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

Чтобы расширить то, что говорит @bgy, безопасный атомный способ создания файла блокировки, если он еще не существует, и сбой, если он этого не делает, - создать временный файл, а затем привязать его к стандарту файл блокировки. Это защищает от другого процесса, создавая файл между вами, проверяя его и создавая.

Вот код файла блокировки из моей почасовой резервной копии script:

echo $$ > /tmp/lock.$$
if ! ln /tmp/lock.$$ /tmp/lock ; then 
        echo "previous backup in process"
        rm /tmp/lock.$$
        exit
fi

Не забывайте удалять как файл блокировки, так и временный файл, когда вы закончите, даже если вы выйдете с ошибкой раньше.

Ответ 9

Используйте этот script:

FILE="/tmp/my_file"
if [ -f "$FILE" ]; then
   echo "Still running"
   exit
fi
trap EXIT "rm -f $FILE"
touch $FILE

...script here...

Этот script создаст файл и удалит его при выходе.