Как определить, работает ли процесс или нет, и использовать его для создания условного сценария оболочки?

В Unix стандартная программа для синхронизации каталогов на двух машинах - rsync. Rsync - быстрый и необычайно универсальный инструмент для копирования файлов. Он может копироваться локально, на / с другого хоста через любую удаленную оболочку или на / из удаленного демона rsync. Он предлагает большое количество опций, которые контролируют каждый аспект его поведения и позволяют очень гибко специфицировать набор файлов, которые нужно скопировать. Он славится своим алгоритмом дельта-передачи, который уменьшает объем данных, отправляемых по сети, отправляя только различия между исходными файлами и существующими файлами в пункте назначения. Rsync широко используется для резервного копирования и зеркалирования и как улучшенная команда копирования для повседневного использования.

Оказывается, есть версия Windows rsync cwRsync. Вот некоторые сведения об установке и использовании cwRsync (хотя он больше ориентирован на использование rsync для резервного копирования)

Поскольку вы не хотите включать какие-либо промежуточные серверы в процесс, одна из проблем, которые вы будете иметь для работы с ним настраивается какая-то переадресация портов, чтобы обеспечить прямой доступ к одному из компьютеров из Интернета (при условии, что машины, которые вы хотите синхронизировать, находятся в разных локальных сетях). Оттуда все должно быть довольно простым.

Еще один вариант, упомянутый cwRsync для аналогичного вопроса, - Unison - использование его через Интернет также потребует настройки перенаправления портов. Что, вообще говоря, является обязательным для любого сервера без решения.

1
задан 28 December 2016 в 04:17

11 ответов

Любое решение, использующее что-то вроде ps aux | grep abc или pgrep abc, ошибочно.

Почему?

Поскольку вы не проверяете, работает ли какой-либо конкретный процесс, вы проверяете если есть какие-либо процессы, которые выполняются в соответствии с abc. Любой пользователь может легко создать и запустить исполняемый файл с именем abc (или который содержит abc где-то в его имени или аргументах), вызывая ложное срабатывание для вашего теста. Существуют различные варианты, которые вы можете применить к ps, grep и pgrep для сужения поиска, но вы по-прежнему не получите надежного теста.

Итак, как я могу надежно проверить

Это зависит от того, что вам нужно для теста.

Я хочу убедиться, что служба abc запущена, а если нет, запустите ее

[d7 ] Это то, для чего предназначены init и upstart. Они запустит сервис и обеспечат его сохранение pidfile в pidfile. Попробуйте снова запустить службу (через init или upstart), и она проверит pidfile и начнет ее, если ее там нет, или прервется, если она уже запущена. Это все еще не на 100% надежнее, но оно как можно ближе.

См. Как проверить, проверяет ли мой игровой сервер ... для других решений.

[d10 ] abc - мой сценарий. Мне нужно убедиться, что работает только один экземпляр моего скрипта.

В этом случае используйте файл блокировки или lockdir. Например,

#!/usr/bin/env bash

if ! mkdir /tmp/abc.lock; then
    printf "Failed to acquire lock.\n" >&2
    exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT  # remove the lockdir on exit

# rest of script ...

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

32
ответ дан 25 May 2018 в 09:11
  • 1
    Хотя это технически верно, я лично сталкивался с такой проблемой в реальной жизни. Большинство программ не изменяют свои имена способами, которые нарушают скрипты. Таким образом, для простых скриптов что-то вроде pgrep или ps вполне адекватно, и ваш подход кажется излишним. Если вы пишете скрипт для публичного распространения, вы должны написать его самым безопасным способом. – Scott Severance 30 June 2012 в 18:21
  • 2
    @ScottSeverance Программы, изменяющие имена, не являются проблемой; что потребует вмешательства независимо. Это другие пользователи, которые запускают одну и ту же программу или другие программы с похожими именами, которые внезапно заставят скрипт получить ложные срабатывания и, таким образом, сделать неправильную вещь. Я просто предпочитаю «работает». а не «в основном работает». – geirha 30 June 2012 в 19:15
  • 3
    Я оговорился. Но многие из нас работают с однопользовательскими системами. И в ситуации с несколькими пользователями, также легко grep для имени пользователя. – Scott Severance 1 July 2012 в 02:03
  • 4
    что, если ваш скрипт не работает во время выполнения и умирает до разблокировки файла? – jp093121 14 August 2014 в 22:41
  • 5
    @ jp093121 Ловушка EXIT запускается при выходе сценария. Выходит ли он из-за того, что он достигает конца скрипта, команды выхода или получает сигнал (который может обрабатываться), выполняется команда rm. Так что, пока он заканчивается после того, как ловушка установлена, замок должен исчезнуть. – geirha 16 August 2014 в 23:30

Это то, что я использую:

#!/bin/bash

#check if abc is running
if pgrep abc >/dev/null 2>&1
  then
     # abc is running
  else
     # abc is not running
fi

На простом английском языке: если «pgrep» возвращает 0, процесс выполняется, в противном случае это не так.

[!d3 ]

Связанные чтения:

Bash Scripting :: String Comparisons

Руководства Ubuntu Сравнение строк

17
ответ дан 25 May 2018 в 09:11
  • 1
    спасибо! Я тоже пробовал это, он тоже отлично работает :) – Nirmik 30 June 2012 в 04:10
  • 2
    pgrep имеет тот же 15-значный предел "особенность" ранее упомянутый, таким образом, например, pgrep gnome-power-manager также потерпел бы неудачу – Thorsen 2 July 2012 в 21:04
  • 3
    Убедитесь, что вы используете параметр -x pgrep: " Только сопоставлять процессы, чье имя (или командная строка, если -f указано), точно соответствует шаблону. & Quot; – Alastair Irvine 21 July 2014 в 09:31

У меня обычно есть pidof -x $(basename $0) в моих скриптах, чтобы проверить, запущен ли он.

4
ответ дан 25 May 2018 в 09:11

Riffing по идее @ rommel-cid, вы можете использовать pidof с || (||) для запуска команды, если процесс не существует и & amp; & amp; для запуска чего-то, если процесс существует, создавая тем самым быстрое if / then / else условное. Например, вот один из них с запущенным процессом (мой браузер Chrome, имя процесса которого «хром») и одно тестирование для процесса, которого не существует. Я подавил стандартный вывод с использованием 1> / dev / null, чтобы он не печатался:

$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
 instead"
it's not running? ok i'll run instead
$
1
ответ дан 25 May 2018 в 09:11

Первое, что пришло мне в голову в связи с вашей проблемой: ps aux | grep -i abc покажет детали процесса, если он работает. Вы можете сопоставить количество строк или времени, в течение которых оно выполняется и сравнивается с нулем или любыми другими манипуляциями. Когда вы запустите указанную выше команду, она покажет вам по крайней мере одну строку вывода, то есть подробно о процессе, созданном командой grep. Поэтому позаботьтесь об этом. Это должно быть простым взломом. Поместите его в скрипт bash и посмотрите, полезен ли он.

0
ответ дан 25 May 2018 в 09:11

Использование start-stop-daemon:

/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2

Он работает как обычный пользователь.

0
ответ дан 25 May 2018 в 09:11

Я обнаружил, что принятый ответ, отправленный @John Vrbanac, не работал для меня, и что ответ, отправленный @geirha, не отвечает на исходный вопрос.

Решение Джона Врбанака не работает чтобы проверить, работает ли PHP-процесс или нет, я запускаю CentOS 7.

Ответ на girha только гарантирует, что экземпляр еще не запущен, прежде чем запускать другой. Это был не оригинальный вопрос, исходный вопрос состоял в том, чтобы проверить, работает ли процесс или нет.

Вот что сработало для меня:

Скажите, что мой процесс имел строку «Джейн», в его имени процесса. Это найдет, если оно работает или нет. Это работает для скриптов BASH и PHP.

ps -aux | grep "[J]ane" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
    echo "It's running"
else
    echo "It's not running"
fi
0
ответ дан 25 May 2018 в 09:11
  • 1
    Ах, так как это сайт Ubuntu Q & amp; A, неудивительно, что некоторые из ответов здесь не работают на CentOS 7, поскольку этот Linux не соответствует теме. Другие версии Linux поддерживаются на unix.stackexchange.com – Elder Geek 11 November 2016 в 23:17
  • 2
    хотя автор ответа использует CentOS, этот ответ по-прежнему действителен для ubuntu. – Phillip -Zyan K Lee- Stockmann 11 November 2016 в 23:34
## bash

## function to check if a process is alive and running:

_isRunning() {
    ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}

## example 1: checking if "gedit" is running

if _isRunning gedit; then
    echo "gedit is running"
else
    echo "gedit is not running"
fi

## example 2: start lxpanel if it is not there

if ! _isRunning lxpanel; then
    lxpanel &
fi

## or

_isRunning lxpanel || (lxpanel &)

Примечание: pgrep -x lxpanel или pidof lxpanel все еще сообщает, что lxpanel работает, даже если он не работает (зомби); поэтому для того, чтобы получить живой и запущенный процесс, нам нужно использовать ps и grep

0
ответ дан 25 May 2018 в 09:11

По состоянию на 23 сентября 2016 года для pgrep требуется опция «-x», чтобы скрипт muru работал.

#!/bin/bash

if pgrep -x "conky" > /dev/null 2>&1
then
  echo "conky running already"
else
  echo "now starting conky"
  conky
fi
exit 0

Я попытался и протестировал вышеупомянутый скрипт на Ubuntu 16.04.1 машина. Наслаждайтесь!

-1
ответ дан 25 May 2018 в 09:11
[F1]
-1
ответ дан 25 May 2018 в 09:11

isProcessRunning () {if [$ (pidof $ 1)> / dev / null]; затем retval = 'true'; else retval = 'false'; Fi; echo $ retval; }

isProcessRunning geany

true

-3
ответ дан 25 May 2018 в 09:11

Другие вопросы по тегам:

Похожие вопросы: