Как проверить, если другой экземпляр мой скрипт работает

В GNU bash, начиная с версии 1.14.7(1)

У меня есть сценарий под названием "abc.sh в" Я должен проверить это с abc.sh только сценария... внутри этого я написал следующее заявление

status=`ps -efww | grep -w "abc.sh" | grep -v grep | grep -v $$ | awk '{ print $2 }'`
if [ ! -z "$status" ]; then
        echo "[`date`] : abc.sh : Process is already running"
        exit 1;
fi

Я знаю, что это'ы не так, потому что каждый раз, когда он выходит, как он нашел свой собственный процесс в 'л. с.' как ее решить? как я могу проверить, что скрипт уже запущен или не из этого скрипта только ?

Комментарии к вопросу (8)

Простой способ проверить, на процессе уже выполнения команды pidof.

if pidof -x "abc.sh" >/dev/null; then
    echo "Process already running"
fi

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

#!/bin/bash
# abc.sh

mypidfile=/var/run/abc.sh.pid

# Could add check for existence of mypidfile here if interlock is
# needed in the shell script itself.

# Ensure PID file is removed on program exit.
trap "rm -f -- '$mypidfile'" EXIT

# Create a file with current PID to indicate that process is running.
echo $$ > "$mypidfile"

...

Обновление: Вопрос теперь изменилось для проверки из самого скрипта. В этом случае, мы надеемся всегда видеть по крайней мере один abc.sh работает. Если есть больше чем один abc.sh тогда мы знаем, что процесс все еще выполняется. Я'd по-прежнему предлагаю использоватьpidofкоманду, которая будет возвращать 2 Пидов, если процесс был уже запущен. Вы могли бы использоватькоманда grep, чтобы отфильтровать тока ПИД, петли в оболочке или даже вернуться, чтобы просто подсчитывать Пидов стуалет`, чтобы обнаружить несколько процессов.

Здесь'ы пример:

#!/bin/bash

for pid in $(pidof -x abc.sh); do
    if [ $pid != $$ ]; then
        echo "[$(date)] : abc.sh : Process is already running with PID $pid"
        exit 1
    fi
done
Комментарии (7)

Я тебя хочу "и pidof" и способ, вот трюк: в

    if pidof -o %PPID -x "abc.sh">/dev/null; then
        echo "Process already running"
    fi

Где -o параметр %цвет рассказывает опустить пид вызова консоли или скрипта. Более подробная информация в pidof Man-странице.

Комментарии (0)

Здесь's один трюк вы'll увидеть в различных местах:

status=`ps -efww | grep -w "[a]bc.sh" | awk -vpid=$$ '$2 != pid { print $2 }'`
if [ ! -z "$status" ]; then
    echo "[`date`] : abc.sh : Process is already running"
    exit 1;
fi

Квадратные скобки вокруг [А] (или выбрать другую букву) предотвратить команда grep найти себя. Это делает команда grep -v с грэп - это уже перебор. Я также убрал команда grep -v С $ $ и починилв awk` части, чтобы сделать то же самое.

Комментарии (0)

Кто-нибудь, пожалуйста, пристрелите меня, если я'м не так вот

Я понимаю, что команды mkdir` операция является атомарной, так что вы могли бы создать блокировку каталог

#!/bin/sh
lockdir=/tmp/AXgqg0lsoeykp9L9NZjIuaqvu7ANILL4foeqzpJcTs3YkwtiJ0
mkdir $lockdir  || {
    echo "lock directory exists. exiting"
    exit 1
}
# take pains to remove lock directory when script terminates
trap "rmdir $lockdir" EXIT INT KILL TERM

# rest of script here
Комментарии (3)

Здесь's, как я делаю это в bash-скрипт:

if ps ax | grep $0 | grep -v $$ | grep bash | grep -v grep
then
    echo "The script is already running."
    exit 1
fi

Это позволяет мне использовать этот фрагмент для любой bash-скрипт. Мне нужно на bash команда grep, потому что при использовании с cron, он создает еще один процесс, который выполняется с помощью /Бен/ш.

Комментарии (1)

Я нашел ответ от @Остин Филлипс на месте. Одно маленькое усовершенствование, которое я'd сделать это добавить -о (игнорировать значение PID самого скрипта) и матч для сценария с базовым именем (т. е. тот же код можно ставить в любой сценарий):

if pidof -x "`basename $0`" -o $$ >/dev/null; then
    echo "Process already running"
fi
Комментарии (0)

Используйте команду PS В немного другой способ, чтобы игнорировать процесс ребенка, а также:

ps -eaf | grep -v grep | grep $PROCESS | grep -v $$
Комментарии (0)

Я обнаружил, что, используя обратные кавычки, чтобы захватить вывод команды в переменную, adversly, дает слишком много ПС ОКС результаты, например, на один запущенный экземпляр abc.sh:

ps aux | grep -w "abc.sh" | grep -v grep | wc -l

возвращает "и 1" и. Однако

count=`ps aux | grep -w "abc.sh" | grep -v grep | wc -l`
echo $count

возвращает "и 2"и

Похоже, используя Апостроф строительства как-то временно создает другой процесс. Может быть причиной того, что topicstarter не мог сделать эту работу. Просто нужно уменьшить $рассчитывать ВАР.

Комментарии (0)

pidof это't работа для меня, поэтому я искал дальше и наткнулся на pgrep

for pid in $(pgrep -f my_script.sh); do
    if [ $pid != $$ ]; then
        echo "[$(date)] : my_script.sh : Process is already running with PID $pid"
        exit 1
    else
      echo "Running with PID $pid"
    fi  
done

Взято из ответов выше и https://askubuntu.com/a/803106/802276

Комментарии (1)

Я создаю временный файл во время выполнения.

Это, как я делаю это:

#!/bin/sh
# check if lock file exists
if [ -e /tmp/script.lock ]; then
  echo "script is already running"
else
# create a lock file
  touch /tmp/script.lock
  echo "run script..."
#remove lock file
 rm /tmp/script.lock
fi
Комментарии (0)

Я не'т хотим, чтобы жестко `abc.sh в проверить, поэтому я использовал следующие:

MY_SCRIPT_NAME=`basename "$0"`
if pidof -o %PPID -x $MY_SCRIPT_NAME > /dev/null; then
    echo "$MY_SCRIPT_NAME already running; exiting"
    exit 1
fi
Комментарии (0)

Это компактный и универсальный

# exit if another instance of this script is running
for pid in $(pidof -x `basename $0`); do
   [ $pid != $$ ] && { exit 1; }
done
Комментарии (0)

[ " и$(pidof -х $(базовое имя $0))" у != усилитель$$ ] &;& выход

https://github.com/x-zhao/exit-if-bash-script-already-running/blob/master/script.sh

Комментарии (0)