Общее решение для предотвращения параллельной работы длинного задания cron?

Средство просмотра по умолчанию очень ограничено, без редактирования и не поддерживает анимированные GIF. Я рекомендую установить gthumb, который находится в репозиториях Ubuntu. Gthumb быстро загружается и предоставляет все основные функции редактирования без усложнения GIMP. Он также служит менеджером изображений, который не накладывает структуру папок на основе даты для изображений. Я предпочитаю подавать по событию или теме - значительно упрощает поиск изображений.

25
задан 25 May 2012 в 14:03

65 ответов

Взгляните на пакет run-one. Из manpage для команды run-one:

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументов. Это часто полезно для cronjob, когда вы хотите, чтобы одновременно выполнялось не более одной копии.

Как и time или sudo, вы просто добавляете его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона посмотрите run-one Dustin Kirkland.

26
ответ дан 25 May 2018 в 10:59

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

29
ответ дан 25 July 2018 в 18:46

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

30
ответ дан 31 July 2018 в 10:33

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

30
ответ дан 31 July 2018 в 11:35

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

30
ответ дан 2 August 2018 в 00:55

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

30
ответ дан 4 August 2018 в 16:25

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

30
ответ дан 6 August 2018 в 01:05

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

30
ответ дан 7 August 2018 в 18:32

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

30
ответ дан 10 August 2018 в 07:12

Взгляните на пакет run-one . Из man-страницы для команды run-one: :

run-one - это сценарий оболочки, который запускает не более одного уникального экземпляра некоторой команды с уникальным набором аргументы.

Это часто полезно для cronjob, если вы хотите, чтобы одновременно выполнялось не более одной копии.

Как time или sudo, вы просто добавьте его в команду. Итак, cronjob может выглядеть так:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

Для получения дополнительной информации и фона, посмотрите сообщение в блоге, введя его Дастином Киркландом.

30
ответ дан 15 August 2018 в 19:12

Очень простой способ установки блокировки:

if mkdir /var/lock/mylock; then
  echo "Locking succeeded" >&2
else
  echo "Lock failed - exit" >&2
  exit 1
fi

Скрипты, которые нужно запустить, требуют создания блокировки. Если блокировка существует, другой скрипт занят, поэтому первый скрипт не может работать. Если файл не существует, ни один скрипт не приобрел блокировку. Таким образом, текущий скрипт получает блокировку.

Для получения дополнительной информации о блокировке bash, проверьте эту страницу

.
3
ответ дан 25 May 2018 в 10:59
  • 1
    Вам также понадобится ловушка EXIT, которая удалит блокировку при выходе. [F1] – geirha 25 May 2012 в 15:23
  • 2
    В идеале вы хотели бы использовать консультативную стаю из процесса, который выполняет команду, которую вы хотите в качестве подзадачи. Таким образом, если все они умирают, стая автоматически освобождается, что не позволяет использовать наличие файла блокировки. Использование сетевого порта будет работать аналогичным образом, хотя это путь меньшее пространство имен, что является проблемой. – Alex North-Keys 19 March 2015 в 20:45

Не нужно устанавливать какой-то причудливый пакет:

#!/bin/bash
pgrep -xf "$*" > /dev/null || "$@"

Быстрее писать сам скрипт, чем запускать «apt-get install», не так ли? Вы можете добавить «-u   $ (id -u)» в pgrep для проверки экземпляров, выполняемых только текущим пользователем.

3
ответ дан 25 May 2018 в 10:59
  • 1
    это не гарантирует один экземпляр. два сценария могут перейти на другую сторону оператора || одновременно, прежде чем либо еще есть шанс запустить скрипт. – Sedat Kapanoglu 9 August 2016 в 23:45
  • 2
    @SedatKapanoglu Предоставлено, что этот сценарий не является оправданием гонки, но исходный вопрос касался длительных рабочих заданий cron (которые запускаются не чаще одного раза в минуту). Если вашей системе требуется больше минуты для создания процесса, у вас есть другие проблемы. Однако, если необходимо по каким-либо другим причинам, вы можете использовать стадо (1) для защиты выше сценария от условий гонки. – Michael Kowhan 11 August 2016 в 01:59
  • 3
    Я использовал это, но для сценария bash, который должен проверять себя. Код следующий: v = $ (pgrep -xf "/ bin / bash $ 0 $ @") [" $ {v / $ BASHPID /} " ! = "" ] & amp; & amp; выход 2 – ahofmann 19 January 2017 в 17:14

См. также [4] Тима Кэя, который выполняет блокировку путем привязки порта по замкнутому адресу, уникальному для пользователя:

http://timkay.com/solo/

] В случае, если его сайт не работает:

Использование:

solo -port=PORT COMMAND

where
    PORT        some arbitrary port number to be used for locking
    COMMAND     shell command to run

options
    -verbose    be verbose
    -silent     be silent

Используйте его так:

* * * * * solo -port=3801 ./job.pl blah blah

Сценарий:

3
ответ дан 25 May 2018 в 10:59

Простое решение от bash-hackers.org, которое работало для меня, использовало mkdir. Это простой способ убедиться, что работает только один экземпляр вашей программы. Создайте каталог с mkdir .lock, который возвращает

true, если создание было успешным и false, если файл блокировки существует, что указывает на то, что в настоящее время работает один экземпляр.

Итак, эта простая функция выполнила всю логику блокировки файлов:

if mkdir .lock; then
    echo "Locking succeeded"
    eval startYourProgram.sh ;
else
    echo "Lock file exists. Program already running? Exit. "
    exit 1
fi


echo "Program finished, Removing lock."
rm -r .lock
0
ответ дан 25 May 2018 в 10:59

Это решение для сценария bash, который должен проверять себя

v=$(pgrep -xf "/bin/bash $0 $@")
[ "${v/$BASHPID/}" != "" ] && exit 0
0
ответ дан 25 May 2018 в 10:59

Это решение для сценария bash, который должен проверять себя

v=$(pgrep -xf "/bin/bash $0 $@")
[ "${v/$BASHPID/}" != "" ] && exit 0
0
ответ дан 25 July 2018 в 18:46

См. также [4] Тима Кэй [4], который выполняет блокировку путем привязки порта по замкнутому адресу, уникальному для пользователя:

http://timkay.com/solo/

В случае, если его сайт не работает:

Использование:

solo -port=PORT COMMAND

where
    PORT        some arbitrary port number to be used for locking
    COMMAND     shell command to run

options
    -verbose    be verbose
    -silent     be silent

Используйте его следующим образом:

* * * * * solo -port=3801 ./job.pl blah blah

Script :

#!/usr/bin/perl -s
#
# solo v1.7
# Prevents multiple cron instances from running simultaneously.
#
# Copyright 2007-2016 Timothy Kay
# http://timkay.com/solo/
#
# It is free software; you can redistribute it and/or modify it under the terms of either:
#
# a) the GNU General Public License as published by the Free Software Foundation;
#    either version 1 (http://dev.perl.org/licenses/gpl1.html), or (at your option)
#    any later version (http://www.fsf.org/licenses/licenses.html#GNUGPL), or
#
# b) the "Artistic License" (http://dev.perl.org/licenses/artistic.html), or
#
# c) the MIT License (http://opensource.org/licenses/MIT)
#

use Socket;

alarm $timeout                              if $timeout;

$port =~ /^\d+$/ or $noport                     or die "Usage: $0 -port=PORT COMMAND\n";

if ($port)
{
    # To work with OpenBSD: change to
    # $addr = pack(CnC, 127, 0, 1);
    # but make sure to use different ports across different users.
    # (Thanks to  www.gotati.com .)
    $addr = pack(CnC, 127, $<, 1);
    print "solo: bind ", join(".", unpack(C4, $addr)), ":$port\n"   if $verbose;

    $^F = 10;           # unset close-on-exec

    socket(SOLO, PF_INET, SOCK_STREAM, getprotobyname('tcp'))       or die "socket: $!";
    bind(SOLO, sockaddr_in($port, $addr))               or $silent? exit: die "solo($port): $!\n";
}

sleep $sleep if $sleep;

exec @ARGV;
3
ответ дан 25 July 2018 в 18:46

Не нужно устанавливать какой-то причудливый пакет:

#!/bin/bash
pgrep -xf "$*" > /dev/null || "$@"

Быстрее написать сам скрипт, чем запустить «apt-get install», не так ли? Вы можете добавить «-u & nbsp; $ (id -u)» в pgrep, чтобы проверить экземпляры, запущенные только текущим пользователем.

3
ответ дан 25 July 2018 в 18:46

Очень простой способ установки блокировки:

if mkdir /var/lock/mylock; then
  echo "Locking succeeded" >&2
else
  echo "Lock failed - exit" >&2
  exit 1
fi

Скрипты, которые нужно запустить, требуют создания блокировки. Если блокировка существует, другой скрипт занят, поэтому первый скрипт не может работать. Если файл не существует, ни один скрипт не приобрел блокировку. Таким образом, текущий скрипт получает блокировку. Когда скрипт закончен, блокировку нужно обновить, удалив блокировку.

Для получения дополнительной информации о блокировке bash, проверьте эту страницу

4
ответ дан 25 July 2018 в 18:46

Вам нужен замок. run-one выполняет задание, но вы также можете заглянуть в flock из пакета util-linux.

Это стандартный пакет, предоставляемый разработчиками ядра, позволяет настраивать больше, чем run-one и все еще очень просто.

1
ответ дан 25 July 2018 в 18:46

Это решение для сценария bash, который должен проверять себя

v=$(pgrep -xf "/bin/bash $0 $@")
[ "${v/$BASHPID/}" != "" ] && exit 0
0
ответ дан 31 July 2018 в 10:33

Простое решение из bash-hackers.org , которое работало для меня, использовало mkdir. Это простой способ убедиться, что работает только один экземпляр вашей программы. Создайте каталог с mkdir .lock, который возвращает

  • true, если создание было успешным, и
  • false, если файл блокировки существует, указывая на то, что в настоящее время выполняется один экземпляр.

Таким образом, эта простая функция выполнила всю логику блокировки файлов:

if mkdir .lock; then
    echo "Locking succeeded"
    eval startYourProgram.sh ;
else
    echo "Lock file exists. Program already running? Exit. "
    exit 1
fi


echo "Program finished, Removing lock."
rm -r .lock
0
ответ дан 31 July 2018 в 10:33

См. также [4] Тима Кэй [4], который выполняет блокировку путем привязки порта по замкнутому адресу, уникальному для пользователя:

http://timkay.com/solo/

В случае, если его сайт не работает:

Использование:

solo -port=PORT COMMAND

where
    PORT        some arbitrary port number to be used for locking
    COMMAND     shell command to run

options
    -verbose    be verbose
    -silent     be silent

Используйте его следующим образом:

* * * * * solo -port=3801 ./job.pl blah blah

Script :

#!/usr/bin/perl -s
#
# solo v1.7
# Prevents multiple cron instances from running simultaneously.
#
# Copyright 2007-2016 Timothy Kay
# http://timkay.com/solo/
#
# It is free software; you can redistribute it and/or modify it under the terms of either:
#
# a) the GNU General Public License as published by the Free Software Foundation;
#    either version 1 (http://dev.perl.org/licenses/gpl1.html), or (at your option)
#    any later version (http://www.fsf.org/licenses/licenses.html#GNUGPL), or
#
# b) the "Artistic License" (http://dev.perl.org/licenses/artistic.html), or
#
# c) the MIT License (http://opensource.org/licenses/MIT)
#

use Socket;

alarm $timeout                              if $timeout;

$port =~ /^\d+$/ or $noport                     or die "Usage: $0 -port=PORT COMMAND\n";

if ($port)
{
    # To work with OpenBSD: change to
    # $addr = pack(CnC, 127, 0, 1);
    # but make sure to use different ports across different users.
    # (Thanks to  www.gotati.com .)
    $addr = pack(CnC, 127, $<, 1);
    print "solo: bind ", join(".", unpack(C4, $addr)), ":$port\n"   if $verbose;

    $^F = 10;           # unset close-on-exec

    socket(SOLO, PF_INET, SOCK_STREAM, getprotobyname('tcp'))       or die "socket: $!";
    bind(SOLO, sockaddr_in($port, $addr))               or $silent? exit: die "solo($port): $!\n";
}

sleep $sleep if $sleep;

exec @ARGV;
3
ответ дан 31 July 2018 в 10:33

Не нужно устанавливать какой-то причудливый пакет:

#!/bin/bash
pgrep -xf "$*" > /dev/null || "$@"

Быстрее написать сам скрипт, чем запустить «apt-get install», не так ли? Вы можете добавить «-u & nbsp; $ (id -u)» в pgrep, чтобы проверить экземпляры, запущенные только текущим пользователем.

3
ответ дан 31 July 2018 в 10:33

Очень простой способ установки блокировки:

if mkdir /var/lock/mylock; then
  echo "Locking succeeded" >&2
else
  echo "Lock failed - exit" >&2
  exit 1
fi

Скрипты, которые нужно запустить, требуют создания блокировки. Если блокировка существует, другой скрипт занят, поэтому первый скрипт не может работать. Если файл не существует, ни один скрипт не приобрел блокировку. Таким образом, текущий скрипт получает блокировку. Когда скрипт закончен, блокировку нужно обновить, удалив блокировку.

Для получения дополнительной информации о блокировке bash, проверьте эту страницу

4
ответ дан 31 July 2018 в 10:33

Вам нужен замок. run-one выполняет задание, но вы также можете заглянуть в flock из пакета util-linux.

Это стандартный пакет, предоставляемый разработчиками ядра, позволяет настраивать больше, чем run-one и все еще очень просто.

1
ответ дан 31 July 2018 в 10:33

Это решение для сценария bash, который должен проверять себя

v=$(pgrep -xf "/bin/bash $0 $@")
[ "${v/$BASHPID/}" != "" ] && exit 0
0
ответ дан 31 July 2018 в 11:35

Простое решение из bash-hackers.org , которое работало для меня, использовало mkdir. Это простой способ убедиться, что работает только один экземпляр вашей программы. Создайте каталог с mkdir .lock, который возвращает

  • true, если создание было успешным, и
  • false, если файл блокировки существует, указывая на то, что в настоящее время выполняется один экземпляр.

Таким образом, эта простая функция выполнила всю логику блокировки файлов:

if mkdir .lock; then
    echo "Locking succeeded"
    eval startYourProgram.sh ;
else
    echo "Lock file exists. Program already running? Exit. "
    exit 1
fi


echo "Program finished, Removing lock."
rm -r .lock
0
ответ дан 31 July 2018 в 11:35

См. также [4] Тима Кэй [4], который выполняет блокировку путем привязки порта по замкнутому адресу, уникальному для пользователя:

http://timkay.com/solo/

В случае, если его сайт не работает:

Использование:

solo -port=PORT COMMAND

where
    PORT        some arbitrary port number to be used for locking
    COMMAND     shell command to run

options
    -verbose    be verbose
    -silent     be silent

Используйте его следующим образом:

* * * * * solo -port=3801 ./job.pl blah blah

Script :

#!/usr/bin/perl -s
#
# solo v1.7
# Prevents multiple cron instances from running simultaneously.
#
# Copyright 2007-2016 Timothy Kay
# http://timkay.com/solo/
#
# It is free software; you can redistribute it and/or modify it under the terms of either:
#
# a) the GNU General Public License as published by the Free Software Foundation;
#    either version 1 (http://dev.perl.org/licenses/gpl1.html), or (at your option)
#    any later version (http://www.fsf.org/licenses/licenses.html#GNUGPL), or
#
# b) the "Artistic License" (http://dev.perl.org/licenses/artistic.html), or
#
# c) the MIT License (http://opensource.org/licenses/MIT)
#

use Socket;

alarm $timeout                              if $timeout;

$port =~ /^\d+$/ or $noport                     or die "Usage: $0 -port=PORT COMMAND\n";

if ($port)
{
    # To work with OpenBSD: change to
    # $addr = pack(CnC, 127, 0, 1);
    # but make sure to use different ports across different users.
    # (Thanks to  www.gotati.com .)
    $addr = pack(CnC, 127, $<, 1);
    print "solo: bind ", join(".", unpack(C4, $addr)), ":$port\n"   if $verbose;

    $^F = 10;           # unset close-on-exec

    socket(SOLO, PF_INET, SOCK_STREAM, getprotobyname('tcp'))       or die "socket: $!";
    bind(SOLO, sockaddr_in($port, $addr))               or $silent? exit: die "solo($port): $!\n";
}

sleep $sleep if $sleep;

exec @ARGV;
3
ответ дан 31 July 2018 в 11:35

Не нужно устанавливать какой-то причудливый пакет:

#!/bin/bash
pgrep -xf "$*" > /dev/null || "$@"

Быстрее написать сам скрипт, чем запустить «apt-get install», не так ли? Вы можете добавить «-u & nbsp; $ (id -u)» в pgrep, чтобы проверить экземпляры, запущенные только текущим пользователем.

3
ответ дан 31 July 2018 в 11:35

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

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