Как скрипту Python перезапустить самого себя?

Имеется скрипт Python с аргументами на входе. При определённых условиях ему необходимо перезапустить самого себя. Я делаю следующее:

import os
import sys
...
if condition_to_restart == True:
    os.execv(sys.argv[0], sys.argv)

Скрипт пытается перезапуститься, но вылезает ошибка OSError: [Errno 13] Permission denied

Как скипту с аргументами на Python перезапустить самого себя?


Ответы (2 шт):

Автор решения: vadim vaduxa

можно запускать "полезный" скрипт (main) в отдельном процессе, а запускающий файл использовать как оболочку для его перезапуска (main_restart):

import multiprocessing, time, sys

def main(event, args):
    """скрипт Python с аргументами на входе"""
    print(f'run {multiprocessing.current_process().name} {args}')
    time.sleep(5)
    event.set()  # При определённых условиях ему необходимо перезапустить самого себя

    time.sleep(10)
    print(f'normal stop {multiprocessing.current_process().name}')
    return

def main_restart(event, args, proc=None):
    """перезапуск скрипта"""
    # while True:
    for _ in range(10):

        event.wait()
        event.clear()
        if proc is not None:
            print(f'terminate {proc.name}')
            proc.terminate()

        proc = multiprocessing.Process(target=main, args=(event, args), daemon=True)
        proc.start()
    return

if __name__ == '__main__':
    Event = multiprocessing.Event()
    Event.set()
    main_restart(Event, sys.argv)

out:

run Process-1 ['D:/SCR/NEW_STAND/sdfas2.py']
terminate Process-1
run Process-2 ['D:/SCR/NEW_STAND/sdfas2.py']
terminate Process-2
run Process-3 ['D:/SCR/NEW_STAND/sdfas2.py']
terminate Process-3
run Process-4 ['D:/SCR/NEW_STAND/sdfas2.py']
...
→ Ссылка
Автор решения: eri

Если коротко - у вас скрипт не отмечен как исполняемый, а в sys.argv[0] будет именно сам скрипт. Можно указать первым аргументом чтоб запустился питон, и он запустил скрипт:

import os
import sys
...
if condition_to_restart == True:
    os.execv(sys.executable, [sys.executable] + sys.argv)
→ Ссылка