Як праверыць, калі іншы асобнік майго скрыпту працуе

ДНУ Баш, версія 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

Я ведаю, што гэта няправільна, таму што кожны раз, калі ён выходзіць, як ён знайшоў свой уласны працэс «сабаку» як вырашыць гэтую праблему? Як я магу праверыць, што сцэнар ужо запушчаны ці не з гэтага сцэнара толькі?

20
PID працэсу пад кіраваннем захоўваецца ў $$, проста ігнараваць яго са спісу Grep -v $$
дададзена аўтар lc2817, крыніца
Яго не бяспечны спосаб праверыць файл у маім case..so я мяркую, каб выкарыстаць гэты спосаб
дададзена аўтар Jatin Bodarya, крыніца
няправільна, я мяркую, каб праверыць толькі з гэтага сцэнара .... таму кожны раз, калі ён правярае свой уласны PID і выходзіць !!!
дададзена аўтар Jatin Bodarya, крыніца
@Grzegorz Хоць на паверхні блакавання файла можа здацца простым, гэта не заўсёды так лёгка выкарыстоўваць файл блакіроўкі права, пераканаўшыся, што ён заўсёды чысціцца правільна, незалежна ад таго, як памёр праграма, ці не правяраць, калі ён можа быць адменена ў выпадку неабходнасці ... Як гэта 100% права ва ўсіх выпадках на самай справе даволі складана. Хоць, гэта сцэнар абалонкі, так што 90% можа быць цалкам прымальным ...
дададзена аўтар twalberg, крыніца
@twalberg Я згодны, што гэта можа быць цяжкім. Я думаю, што з дапамогай файла Pid будзе лепш, так як мы можам праверыць, сапраўды, нават калі ён не быў ачышчаны. Мой голас ідзе ў Pid адказ файла.
дададзена аўтар Grzegorz Żur, крыніца
Гэта прасцей выкарыстоўваць якой-небудзь файл блакіроўкі. Калі файл прысутнічае яшчэ адзін асобнік працуе. Проста пераканайцеся, што файл будзе выдалены.
дададзена аўтар Grzegorz Żur, крыніца
У чым праблема з гэтым сцэнарам? Гэта здаецца правільным, вы ігнаруеце PID бягучага працэсу і толькі правяраць, ці ёсць іншыя abc.sh працэс.
дададзена аўтар Adam Siemion, крыніца

11 адказы

Просты спосаб праверыць працэс ужо выконваецца гэта pidof каманды.

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

Акрамя таго, ваш сцэнар стварыць PID-файл, калі ён выконвае. Гэта тое простае практыкаванне праверкі на наяўнасць файла 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"

...

Update: The question has now changed to check from the script itself. In this case, we would expect to always see at least one abc.sh running. If there is more than one abc.sh, then we know that process is still running. I'd still suggest use of the pidof command which would return 2 PIDs if the process was already running. You could use grep to filter out the current PID, loop in the shell or even revert to just counting PIDs with wc to detect multiple processes.

Вось прыклад:

#!/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
35
дададзена
<�Код> $$ y'all - Што гэта магія рабіць?
дададзена аўтар Pureferret, крыніца
і што, калі іншы сцэнар «xyzabc.sh» таксама працуе ў той жа час? Адказ на гэтае пытанне добра, але не так бяспечна.
дададзена аўтар Jatin Bodarya, крыніца
<�Код> pidof не зьяўляецца, каб быць стандартным інструментам. Ён не даступны ў маёй версіі RedHat.
дададзена аўтар swdev, крыніца
@ User95711 На маёй машыне, па меншай меры, pidof ня падабраць xyzabc.sh , калі pidof -x abc.sh запускаецца. Калі вы хочаце бяспекі, вам патрэбен шырокі рэсурс блакавання сістэмы, якая чаму людзі мяркуюць выкарыстоўваць PID-файл або унікальнае імя каталога. Выкарыстанне імёнаў у спісе працэсаў не з'яўляецца добрым спосабам праверыць катэгарычна працэс запушчаны Ці, так як імёны могуць быць падменены.
дададзена аўтар Austin Phillips, крыніца
@Pureferret Глядзіце раздзел Спецыяльныя параметры Баш чалавека старонку , якая абвяшчае $ раскрываецца ў ідэнтыфікатар працэсу абалонкі. У() подоболочке, яна пашыраецца ў ідэнтыфікатар працэсу бягучай абалонкі, а не подоболочки.
дададзена аўтар Austin Phillips, крыніца
Прыклад абнаўлення кода можа быць больш транспартабельныя шляхам замены двух асобнікаў <�б> abc.sh з <�Ь> $ 0 , не так, што незалежна ад таго, што Баш скрыпт, які вы змесціце яго ў ім будзе ведаць яго ўласнае імя.
дададзена аўтар frederickjh, крыніца

Я вы хочаце метад «pidof», тут ёсць хітрасць:

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

Там, дзе -o% PPID параметр паказвае апусціць ИДП выклікалай абалонкі або сцэнара абалонкі. Больш падрабязную інфармацыю ў pidof мужчына старонкі.

16
дададзена

Вось адзін трук, вы будзеце бачыць у розных месцах:

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 Grep -v трохі непатрэбнымі. Я таксама выдаліў Grep -v $$ і выправіў AWK часткі, каб зрабіць тое ж самае.

11
дададзена

Кто-то, калі ласка, страляйце мяне, калі я памыляюся тут

I understand that the mkdir operation is atomic, so you could create a lock directory

#!/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
6
дададзена
Так, я коратка падумаў, але не быў упэўнены, наколькі добра яна будзе працаваць, я спрабую атрымаць гэтую працу для майго сцэнара, які правярае ВХосты даменаў і знайшоў «pgrep -f» згадваецца (у іншым пасце) лепшы варыянт да гэтага часу.
дададзена аўтар Mike Q, крыніца
Гэта працуе, але ён пакідае адзін у становішчы, не ведаючы, калі працэс на самай справе працуе ці не, калі б яна зламаецца (патэнцыйна)?
дададзена аўтар Mike Q, крыніца
@MikeQ ёсць шмат дадатковых крокаў, якія мы можам зрабіць. Такія, як напісанне PIDFILE ў каталогу, і калі мы не можам стварыць рэж, паколькі ён існуе, то праверце Іка ў PidFile фактычна адпавядае запушчанаму асобніку праграмы.
дададзена аўтар glenn jackman, крыніца

Выкарыстоўвайце каманду PS у крыху па-іншаму, як ігнараваць даччыны працэс, а таксама:

ps -eaf | grep -v grep | grep $PROCESS | grep -v $$
3
дададзена

Я ствараю часовы файл падчас выканання.

Вось як я гэта раблю:

#!/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
2
дададзена

Я не хачу, каб жорстка 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
1
дададзена

pidof wasn't working for me so I searched some more and came across 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

Taken in part from answers above and https://askubuntu.com/a/803106/802276

1
дададзена
Гэта быў адзіны, хто сапраўды працаваў для мяне, вы павінны скакаць праз некалькі стартавых абручоў (як вы называеце сцэнар) для іншых метадаў і з дапамогай файлаў блакавання робіце гэта так, калі ён выходзіць з ладу ён не будзе зноў пачаць у сувязі з замыкаць быць там.
дададзена аўтар Mike Q, крыніца

Вось як я гэта раблю ў Баш скрыпт:

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

Гэта дазваляе мне выкарыстоўваць гэты фрагмент кода для любога Баш скрыпт. Мне трэба Grep Баша, таму што пры выкарыстанні з хрон, гэта стварае яшчэ адзін працэс, які выконвае яго, выкарыстоўваючы/bin/ш.

1
дададзена

Я выявіў, што з дапамогай двукоссі для захопу высновы каманды ў пераменны, adversly, yeilds адзін занадта шмат пс Окс вынікі, напрыклад, для аднаго выконвацца асобніка 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 не можа зрабіць гэтую працу. Проста трэба памяншаць $ рахункі вар.

1
дададзена

Я лічу, што адказ ад @Austin Phillips плямы на. Адно невялікае ўдасканаленне, якое я хацеў бы зрабіць, гэта дадаць -o (ігнараваць PID самага скрыпту) і матч за сцэнар з базавым імем (то бок для тых жа код можа быць уведзены ў любы сцэнар):

if pidof -x "`basename $0`" -o $$ >/dev/null; then
    echo "Process already running"
fi
0
дададзена