title: How to terminate loop gracefully when CTRL+C was pressed in python
body: <p>I'm rather new to python and I'm stuck with the following problem.
  I have a script that processes files one-by-one and writes output into separate files according to input file name. Sometimes I need to break the script, but I'd like to let it finish processing current file and then terminate (to avoid result files with incomplete information). How to code this behavior in python?</p>
  <p>Here is what I tried.</p>
  <p>a) Try-except block</p>
  <pre><code>x = 1
  print &quot;Script started.&quot;
  while True:
   try:
    print &quot;Processing file #&quot;,x,&quot;started...&quot;,
    # do something time-cosnuming
    time.sleep(1)
    x += 1
    print &quot; finished.&quot;
   except KeyboardInterrupt:
    print &quot;Bye&quot;
    print &quot;x=&quot;,x
    sys.exit()
  
  sys.exit()
  </code></pre>
  <p>Output:</p>
  <pre><code>Script started.
  Processing file # 1 started...  finished.
  Processing file # 2 started...  finished.
  Processing file # 3 started... Bye
  x= 3
  </code></pre>
  <p>Iteration #3 is not finished gracefully.</p>
  <p>b) sys.excepthook</p>
  <pre><code>OriginalExceptHook = sys.excepthook
  def NewExceptHook(type, value, traceback):
  global Terminator
      Terminator = True
      if type == KeyboardInterrupt:
          #exit(&quot;\nExiting by CTRL+C.&quot;)   # this line was here originally
          print(&quot;\n\nExiting by CTRL+C.\n\n&quot;)
      else:
          OriginalExceptHook(type, value, traceback)
  sys.excepthook = NewExceptHook
  
  global Terminator
  Terminator = False
  
  x = 1
  while True:
    print &quot;Processing file #&quot;,x,&quot;started...&quot;,
    # do something time-cosnuming
    time.sleep(1)
    x += 1
    print &quot; finished.&quot;
    if Terminator:
     print &quot;I'll be back!&quot;
     break
  
  print &quot;Bye&quot;
  print &quot;x=&quot;,x
  sys.exit()
  </code></pre>
  <p>Output:</p>
  <pre><code>Script started.
  Processing file # 1 started...  finished.
  Processing file # 2 started...  finished.
  Processing file # 3 started...
  
  Exiting by CTRL+C.
  </code></pre>
  <p>Iteration #3 is not finished gracefully.</p>
  <h3>UPD#1</h3>
  <p>@mguijarr , I slightly modified code like this:</p>
  <pre><code>import time, sys
  
  x = 1
  print &quot;Script started.&quot;
  stored_exception=None
  
  while True:
      try:
          print &quot;Processing file #&quot;,x,&quot;started...&quot;,
          # do something time-cosnuming
          time.sleep(1)
          print &quot;Processing file #&quot;,x,&quot;part two...&quot;,
          time.sleep(1)
          print &quot; finished.&quot;
          if stored_exception:
              break
          x += 1
      except KeyboardInterrupt:
          print &quot;[CTRL+C detected]&quot;,
          stored_exception=sys.exc_info()
  
  print &quot;Bye&quot;
  print &quot;x=&quot;,x
  
  if stored_exception:
      raise stored_exception[0], stored_exception[1], stored_exception[2]
  
  sys.exit()
  </code></pre>
  <p>The output is (tested using &quot;Python 2.7.6 :: Anaconda 2.0.0 (64-bit)&quot; on Win7-64bit):</p>
  <pre><code>Script started.
  Processing file # 1 started... Processing file # 1 part two...  finished.
  Processing file # 2 started... Processing file # 2 part two...  finished.
  Processing file # 3 started... [CTRL+C detected] Processing file # 3 started... Processing file # 3 part two...  finished.
  Bye
  x= 3
  Traceback (most recent call last):
    File &quot;test2.py&quot;, line 12, in &lt;module&gt;
      time.sleep(1)
  KeyboardInterrupt
  </code></pre>
  <p>In this case iteration #3 was effectively restarted, which looks odd and is not a desired behavior. Is it possible to avoid this?</p>
  <p>I removed commas in 'print' statements and added more stuff to see that iteration is actually restarted:</p>
  <pre><code>import time, sys
  
  x = 1
  y = 0
  print &quot;Script started.&quot;
  stored_exception=None
  
  while True:
      try:
          y=x*1000
          y+=1
          print &quot;Processing file #&quot;,x,y,&quot;started...&quot;
          y+=1
          # do something time-cosnuming
          y+=1
          time.sleep(1)
          y+=1
          print &quot;Processing file #&quot;,x,y,&quot;part two...&quot;
          y+=1
          time.sleep(1)
          y+=1
          print &quot; finished.&quot;,x,y
          y+=1
          if stored_exception:
              break
          y+=1
          x += 1
          y+=1
      except KeyboardInterrupt:
          print &quot;[CTRL+C detected]&quot;,
          stored_exception=sys.exc_info()
  
  print &quot;Bye&quot;
  print &quot;x=&quot;,x
  print &quot;y=&quot;,y
  
  if stored_exception:
      raise stored_exception[0], stored_exception[1], stored_exception[2]
  
  sys.exit()
  </code></pre>
  <p>and the output is:</p>
  <pre><code>Script started.
  Processing file # 1 1001 started...
  Processing file # 1 1004 part two...
   finished. 1 1006
  Processing file # 2 2001 started...
  Processing file # 2 2004 part two...
  [CTRL+C detected] Processing file # 2 2001 started...
  Processing file # 2 2004 part two...
   finished. 2 2006
  Bye
  x= 2
  y= 2007
  Traceback (most recent call last):
    File &quot;test2.py&quot;, line 20, in &lt;module&gt;
      time.sleep(1)
  KeyboardInterrupt
  </code></pre>