pause/resume a python script in middle

Question:

Can I have a running python script(under Windows)being paused in the middle by user , and resume again when user decides ?

There is a main manager program which generates,loads and runs other python scripts (by calling python script.py from console).I don’t have GUI and user can interact via console.I want my main program be able to respond to user pause/resume command for the running script.Should I define a thread? Whats the approach ?

Edit/Update :

Let’s say I have a small python application with frontend which has various functions. I have a RUN command which runs python scripts in background .I want to implement a PAUSE feature which would pause the running python script . When the user commands RUN again then the python script should resume
running .
using raw_input() or print() forces user to issue command.But in this case, we don’t know when user want to interrupt/pause/issue a command.So usual input/print is not usable.

Asked By: user845459

||

Answers:

Have you tried the obvious and print a prompt then read a line from stdin? That will pause your whole script.

What you asked in your original question isn’t very clear, so if this doesn’t do what you want, can you explain why?

Answered By: Bryan Oakley

I don’t understand very well your approach but every time a user needs to press a enter to continue the script you should use:

input() #for python 3k
raw_input() #for python 2k

without assigning the receiving answer to a variable.

Answered By: Serban Razvan

Ok, from what I’ve seen in my searches on this, even with threading, sys.stdin is going to work against you, no matter how you get to it (input(), or even sys.stdin.read(), .readline(), etc.), because they block.

Instead, write your manager program as a socket server or something similar.

Write the scripts as generators, which are designed to pause execution (every time it hits a yield), and just call next() on each one in turn, repeatedly. You’ll get a StopIteration exception when a script completes.

For handling the commands, write a second script that connects to the manager program’s socket and sends it messages, this will be the console interface the user interacts with (later, you could even upgrade it to a GUI without altering much elsewhere).

The server picks these commands up before running the next iteration on the scripts, and if a script is paused by the user, the manager program simply doesn’t call next() on that script until the user tells it to run again.

I haven’t tested this, but I think it’ll work better than making threads or subprocesses for the external scripts, and then trying to pause (and later kill) them.


This is really out of my depth, but perhaps running the scripts in the background and using kill -stop and kill -cont to pause and continue will work (assuming Linux)?

Answered By: Erik Youngren

If it were unix I’d recommend signal, but here is a crude version that does what you ask.

import time

while True:
    try:
        time.sleep(1)  # do something here
        print '.',

    except KeyboardInterrupt:
        print 'nPausing...  (Hit ENTER to continue, type quit to exit.)'
        try:
            response = raw_input()
            if response == 'quit':
                break
            print 'Resuming...'
        except KeyboardInterrupt:
            print 'Resuming...'
            continue

Use Ctrl+C to pause, and ENTER to resume. Ctrl+Break can probably be used as a harsh kill, but I don’t have the key on this keyboard.

A more robust version could use select on a pipe/socket, or even threads.

Answered By: Gringo Suave

You can make a simple workaround by creating a PAUSEFILE. Your to-be-paused script may periodically check for existence (or content) of such file.

User’s PAUSE command can create (or fill with proper content) such file.

I have used this approach in a similar situation, where I wanted to be able to pause my Python scripts and resume them later. They contain something like

if os.path.isfile(PAUSEFILE):
  raw_input('Remove ' + PAUSEFILE + ' and hit ENTER to continue')

in their main loops.

It is nasty and could be broken if the code really depended on it, but for the use cases, where the pause is done by users at random, I guess it will not matter.

The PAUSE command is simply touch $PAUSEFILE.

Answered By: ciakval

If you’re launching your python script from the windows command window, you can use msvcrt.kbhit() as a non-blocking key press check as implemented here:
http://code.activestate.com/recipes/197140-key-press-detection-for-windows-text-only-console-/

Answered By: jonincanada

I found so hacky those responses, while being interesting too.

The best approach is the https://stackoverflow.com/a/7184165/2480481 doing it using KeyboardInterrupt exception.

As i noticed nobody mention “using a debugger”, i’ll do it.

Install pdb, Python debugger with pip install pdb.
Follow that to make your script pausable https://stackoverflow.com/a/39478157/2480481 by Ctrl+c instead of exit it.

The main benefit of using a debugger (pdb) is that you can inspect the variables, values, etc. This is far way more powerfull than just pause/continue it.

Also, you can add Ipython interface with pdb attached to debug your app when crashes. Look at: https://stackoverflow.com/a/14881323/2480481

Answered By: m3nda

In Windows, you can suspend/resume running Python scripts . Type resmon on CMD or via Run command (Windows+R). Locate your Python script process and right-click>Suspend Process. This will unlock CPU usage but not RAM. 😉

Answered By: Prayson W. Daniel

You can use Pdb module in python.
Eventhough it’s a debugger, in your case it helps you pass and continue wherever you have a breakpoint in the code.

Also when you resume you can get a glimpse of where it is paused and what are the values of the variables etc. Which will be very helpful.

python debugger – pdb

Answered By: Jim Todd

I was searching for this for so long. Hence decided to solve it myself.
Below code works just fine for me.

Before starting the loop, simply print an instruction line for users.

Here’s my code –

import time
start = 0

run = True
while run == True:        
    try :
        # Loop Code Snippet
        for i in range(start,100):
            time.sleep(2)
            print(i)
            start = i+1
    except :
        print("""~~~~~~~Code interupted~~~~~~~ 
        n Press 1 to resume 
        n Press 2 to quit""")
        res = input()
        if res == "1" :
            print("1")
            # pass and resume code
            pass
        if res == "2" :
            print("2") 
            #Save output and quit code
            run = False
        pass  #Safety pass if case user press invalid input

This code can be interrupted by using conventional way of "Ctrl + C ".

How this works –
When code is interrupted, "keyboard interrupt" error is raised. Due to which error handler "Try:Except" will go to Except block ( where user can provide an input to either resume, save current output or quit code )

For resume functionality, loop’s current position is saved and is fed back into as start for loop.

There are many improvement points here, look forward to suggestions.

Answered By: Dhruv Arya

in Linux terminal:

sudo pkill -STOP python3
sudo pkill -CONT python3

if you want to do it from within python, then create config.ini with text

[control]
pausescript = False

and then in python script:

from configparser import ConfigParser
config = ConfigParser()
config.read("config.ini")

and somewhere in the script where it loops:

  pauseScript = True
  while pauseScript:
    config.read("config.ini")
    pauseScript = config.getboolean('control', 'pausescript')
    if pauseScript:
      print("Script paused. Resume by change config setting to False.                                    ",end="r")
      time.sleep(0.3)

then you control the script by putting True or False in the config.ini file

Answered By: Jan
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.