2015-03-30 4 views
2

Я хочу знать, как я могу остановить мой текущий скрипт python, когда он уже запущен.Как остановить мой скрипт python при запуске другого скрипта python?

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

В настоящее время я пытаюсь этот код:

if os.system("ps ax | grep sample_python.py") == True: 
    print "fail" 
    exit(0) 
else: 
    print "pass" 

Приведенный выше код выглядит как это имя оглавлению питон .. но это всегда идти к другому петли вместо того, чтобы идти в, если цикл и выход ..

Итак, для тестирования я запускаю свой скрипт, а на другом терминале снова запускаю свой сценарий. Первый скрипт не останавливается, но 2-й питон не входит в цикл if для вывода сообщения об ошибке.

Как это исправить?


Хорошо, я нашел тупую вещь, и я хочу, чтобы увидеть, если кто-то может помочь мне идти вокруг него .. Так что моя точка была убить питон, который только начал, если другой питон в настоящее время работает .. но тупое дело .. так как я запускаю свой python и запускаю проверку кода внутри этого python .. он всегда выйдет .. потому что как только я запустим python, PID будет создан и будет запущен ...

Итак, запуск python -> pid создан и запущен -> проверить, запущен ли python -> yes python is running -> exit.

Я хочу посмотреть, есть ли способ сделать запуск python -> проверить, запущен ли python или нет -> если он запущен, убить текущий python, а не тот, который был запущен.

+1

grep найдет себя, если не найдет соответствия –

+0

Способ диагностики проблемы, которую вы представляете, - это сначала ввести в командной строке 'ps ax ...' как при запуске вашего скрипта, так и когда не проверять, есть ли у вас правой командной строки. Затем вы пишете скрипт python, который просто печатает результат вызова 'os.system (...', снова в обоих случаях, чтобы проверить, есть ли разница. Тогда вы должны будете написать сценарий, который вам нужен. – quamrana

+0

You могут использовать 'pgrep' и' pkill' для поиска и уничтожения процессов, не включая сам процесс grep (есть также различные утилиты оболочки, чтобы гарантировать, что только одна копия чего-то запущена, хотя они могут не соответствовать вашей ситуации) – DNA

ответ

7

Файл блокировки с PID текущего процесса является более систематическим способом для этого. Программа просто проверяет с самого начала, существует ли файл PID и заблокирован (flock или lockf); если это так, это означает, что еще один экземпляр этой программы все еще запущен. Если нет, он создает (или переписывает) файл PID и блокирует его.

Блокировка стада/замка имеет то преимущество, что операционная система автоматически удаляет блокировку в случае завершения программы.

Смотрите здесь, как сделать это в Python:

Python: module for creating PID-based lockfile?

+0

Just FYI, скрипт, связанный с принятым ответом, был обновлен с момента написания ответа и имеет большую зависимость от пакета Mercurial, чем он первоначально делал. Это, возможно, не проблема для OP. – detly

+0

Да - PID является стандартным для этого. См. Также http://stackoverflow.com/questions/688343/reference-for-proper-handling-of-pid-file-on-unix – Jonathan

0

os.system() возвращает значение выхода команды, которая была запущена. Если ps был успешным, он возвращает 0, что не эквивалентно True. Вы можете явно проверить, вернула ли команда нуль, которая должна привести вас в блок if.

Редактировать: Для этого необходимо os.subprocess. Эти четыре команды должны получить то, что вы хотите.

p1 = subprocess.Popen(['ps', 'ax'], stdout=subprocess.PIPE) 
p2 = subprocess.Popen(['grep', 'bash'], stdin=p1.stdout, stdout=subprocess.PIPE) 
p3 = subprocess.Popen(['wc', '-l'], stdin=p2.stdout, stdout=subprocess.PIPE) 
count = int(p3.stdout.read()) 
if count > 1: 
    print('yes') 

Замените «bash» на имя вашего скрипта. Что это такое - получить список запущенных процессов, каналы, которые выводят в grep, чтобы вывести все, кроме вашего скрипта (или экземпляры bash в образце кода), каналы, которые выводят в wc, чтобы получить количество строк, а затем запрашивают этот процесс для его stdout, который является счетчиком экземпляров сценария, который в настоящее время запущен. Затем вы можете использовать эту переменную count в выражении if, где, если работает более одного экземпляра, вы можете прервать выполнение.

+0

спасибо но теперь у меня проблема. Когда я запускаю свое кодирование 'if os.system (« ps ax | grep sample_python.py »)' .. он всегда печатает '5440 pts/0 S + 0:00 sh -c ps ax | grep sample_python.py' и '5442 pts/0 S + 0:00 grep sample_python.py' и выйдет сейчас .. даже если мой python не запущен или просто запущен. ' – Tim

+0

Если оба сценария имеют одно и то же имя, звучит, тогда ps/grep всегда будет возвращать хотя бы одну строку. Таким образом, вы можете запустить outpu t grep через wc, чтобы увидеть, есть ли две или более строк. Альтернативный подход заключался бы в создании файла блокировки, который удаляется в конце запуска скрипта, - тогда вы можете проверить, существует ли он, и если не создать его и запустить скрипт. – devinformatics

+0

Я не понимаю .. вы можете объяснить немного больше? – Tim

0

Более вещий путь:

import os 
import psutil 

script_name = os.path.basename(__file__) 
if script_name in [p.name() for p in psutil.get_process_list()]: 
    print "Running" 
-1

Поскольку os.system ("пс топор | Grep sample_python.py") возвращает 0 . Это не верно.

Посмотрите на этот вопрос: Assign output of os.system to a variable and prevent it from being displayed on the screen

Вы должны написать

os.popen('cat /etc/services').read() 

Но такой путь всегда будет идти к «не удалось», потому что ваш скрипт уже запущен. Вы должны рассчитывать количество возвращаемых строк ...

Посмотрите здесь как вариант одного экземпляра:

Python: single instance of program

Я написал такой сценарий. Я создал файл с любым именем в начале и удалил в конце. Это был сценарий демона. В начале я проверил, существует ли этот файл.

Не плохой вариант здесь Ensure a single instance of an application in Linux:

import fcntl 
pid_file = 'program.pid' 
fp = open(pid_file, 'w') 
try: 
    fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB) 
except IOError: 
    # another instance is running 
    sys.exit(1) 
0

Вместо использования grep, почему бы не создать файл блокировки? Один экземпляр вашей программы создает файл в известном месте и удаляет его при выходе. Любой другой экземпляр должен проверить наличие этого файла и продолжать работать только в том случае, если он уже существует.

os.open() функция имеет специфические флаги для этого:

import os 

LOCKFILE_LOCATION = "/path/to/lockfile" 

try: 
    os.open(LOCKFILE_LOCATION, os.O_CREAT|os.O_WRONLY|os.O_EXCL) 
    # Maybe even write the script's PID to this file, just in case you need 
    # to check whether the program died unexpectedly. 
except OSError: 
    # File exists or could not be created. Can check errno if you really 
    # need to know, but this may be OS dependent. 
    print("Failed to create lockfile. Is another instance already running?") 
    exit(1) 
else: 
    print("Pass") 
    # Run the rest of the program. 
    # Delete the file 
    os.remove(LOCKFILE_LOCATION) 

Попробовать это, поставив, скажем, после `печати («Pass») и запуск нескольких экземпляров этого сценария; все, кроме одного, должны потерпеть неудачу.

Смежные вопросы