Как мне убедиться, что мой bash-скрипт еще не запущен? - PullRequest
13 голосов
/ 17 сентября 2009

У меня есть скрипт bash, который я хочу запускать каждые 5 минут из cron ... но есть вероятность, что предыдущий запуск скрипта еще не завершен ... в этом случае я хочу, чтобы новый запуск просто завершился , Я не хочу полагаться только на файл блокировки в / tmp .. Я хочу убедиться, что процесс действительно запущен, прежде чем я выполню файл блокировки (или любой другой) ...

Вот то, что я украл из интернета до сих пор ... как я могу немного поумнеть? или есть совершенно другой способ, который лучше?

if [ -f /tmp/mylockFile ] ; then
  echo 'Script is still running'
else
  echo 1 > /tmp/mylockFile
  /* Do some stuff */
  rm -f /tmp/mylockFile
fi

Ответы [ 13 ]

0 голосов
/ 27 июля 2014

Поскольку решение с сокетами еще не было упомянуто, стоит указать, что сокеты могут использоваться в качестве эффективных мьютексов. Создание сокета - это атомарная операция, как mkdir, как указал Gunstick, поэтому сокет подходит для использования в качестве блокировки или мьютекса.

Perl-скрипт Тима Кея 'Solo' - очень маленький и эффективный скрипт, позволяющий одновременно запускать только одну копию скрипта. Он был разработан специально для использования с заданиями cron, хотя он отлично работает и для других задач, и я очень эффективно использовал его для заданий, не относящихся к кробам.

У Solo есть одно преимущество перед другими методами, упомянутыми до сих пор, в том, что проверка выполняется вне сценария, для которого вы хотите запустить только одну копию. Если сценарий уже запущен, второй экземпляр этого сценария никогда не будет запущен. Это в отличие от выделения блока кода внутри скрипта, который защищен блокировкой. РЕДАКТИРОВАТЬ: Если flock используется в задании cron, а не внутри скрипта, то вы также можете использовать это, чтобы предотвратить запуск второго экземпляра скрипта - см. Пример ниже.

Вот пример того, как вы можете использовать его с cron:

*/5 * * * * solo -port=3801 /path/to/script.sh args args args

# "/path/to/script.sh args args args" is only called if no other instance of
# "/path/to/script.sh" is running, or more accurately if the socket on port 3801
# is not open. Distinct port numbers can be used for different programs so that
# if script_1.sh is running it does not prevent script_2.sh from starting, I've
# used the port range 3801 to 3810 without conflicts. For Linux non-root users 
# the valid port range is 1024 to 65535 (0 to 1023 are reserved for root).

* * * * * solo -port=3802 /path/to/script_1.sh
* * * * * solo -port=3803 /path/to/script_2.sh

# Flock can also be used in cron jobs with a distinct lock path for different
# programs, in the example below script_3.sh will only be started if the one
# started a minute earlier has already finished.

* * * * * flock -n /tmp/path.to.lock -c /path/to/script_3.sh

Ссылки:

Надеюсь, это поможет.

0 голосов
/ 08 января 2013

Вы можете использовать это:

pgrep -f "/bin/\w*sh .*scriptname" | grep -vq $$ && exit
0 голосов
/ 17 сентября 2009

Вы всегда можете просто:

 if ps -e -o cmd | grep scriptname > /dev/null; then 
     exit
 fi

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...