rm -rf ~/Library/Developer/Xcode/DerivedData
Вот один прием, который вы увидите в разных местах:
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
Скобки вокруг [a]
(или выберите другую букву) не позволяют grep
найти себя. Это делает бит grep -v grep
ненужным. Я также удалил grep -v $
и исправил часть awk
, чтобы выполнить то же самое.
Кто-то, пожалуйста, застрелите меня, если я здесь не прав
Я понимаю, что операция 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
Если вам нужен метод "pidof", то здесь есть хитрость:
if pidof -o %PPID -x "abc.sh">/dev/null; then
echo "Process already running"
fi
Где параметр -o %PPID
указывает, что нужно опустить pid вызывающей оболочки или сценария оболочки. Более подробная информация на справочной странице pidof
.
Более простым способом проверки уже выполняющегося процесса является команда 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"
...
Обновление: Теперь вопрос изменен для проверки из самого скрипта. В этом случае мы ожидаем, что всегда будет запущен хотя бы один abc.sh
. Если их более одного abc.sh
, то мы знаем, что процесс все еще выполняется. Я бы по-прежнему предлагал использовать команду pidof
, которая выдаст 2 PID, если процесс уже запущен. Вы можете использовать grep
, чтобы отфильтровать текущий PID, выполнить цикл в оболочке или даже вернуться к простому подсчету PID с помощью wc
для обнаружения нескольких процессов.
Вот пример:
#!/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
Вот как я это делаю в скрипте bash:
if ps ax | grep [110] | grep -v $ | grep bash | grep -v grep
then
echo "The script is already running."
exit 1
fi
Это позволяет мне использовать этот фрагмент для любого скрипта bash. Мне нужно было grep bash, потому что при использовании cron он создает другой процесс, который выполняет его, используя /bin/sh.
Используйте команду PS немного по-другому, чтобы игнорировать и дочерний процесс:
ps -eaf | grep -v grep | grep $PROCESS | grep -v $
Я нахожу ответ от @Austin Phillips точным. Одно небольшое улучшение, которое я хотел бы сделать, это добавить -o (чтобы игнорировать pid самого скрипта) и сопоставить скрипт с базовым именем (т. Е. Тот же код можно вставить в любой скрипт):
if pidof -x "`basename [110]`" -o $ >/dev/null; then
echo "Process already running"
fi
pidof
не работал для меня, поэтому я искал еще немного и наткнулся на 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/ а / 803106/802276
Я создаю временный файл во время выполнения.
Вот как я это делаю:
#!/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
Я не хотел жестко кодировать abc.sh
в чеке, поэтому я использовал следующее:
MY_SCRIPT_NAME=`basename "[110]"`
if pidof -o %PPID -x $MY_SCRIPT_NAME > /dev/null; then
echo "$MY_SCRIPT_NAME already running; exiting"
exit 1
fi
Я обнаружил, что использование обратных галочек для записи вывода команды в переменную, к сожалению, дает слишком много результатов ps aux , например для одного запущенного экземпляра 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»
Похоже, что использование конструкции backtick каким-то образом временно создает другой процесс. Может быть причина, по которой автор темы не может сделать эту работу. Просто нужно уменьшить переменную $ count.