3

Is there a proper way to create a script that loops through files in a folder and executes a subprocess that can be externally killed with Ctrl C? I have something like the following embedded in a pipeline and cannot Ctrl C it from the command line when the main process is killed.

Example script:

import subprocess
import os
import sys

input_directory = sys.argv[1]

for file in os.listdir(os.path.abspath(input_directory)):
    output = file + "_out.out"
    command = ['somescript.py', file, output]
    try:
        subprocess.check_call(command)
    except:
        print "Command Failed"

I would then execute program:

Example_script.py /path/to/some/directory/containing/files/

While it is looping, if I see the command failed, I want use Ctrl C. However, it fails and continues to run additional subprocesses despite the main script has been destroyer with Ctrl C. Is there a proper way to write something like this that can kill the childs (additional subprocess) with Ctrl C?

Any help, or pointing me in the direction is appreciated greatly. I am currently looking for a good method to do.

2
  • 1
    Why not just exit your program when you catch the exception, after printing "Command Failed"? - You can get more complicated than this by adding signal handling to your code that gets called when a child dies, but in this case, it seems like you just want to stop looping when you get a failure. ... or are you saying that you don't get an exception in this case? Commented Mar 21, 2019 at 3:37
  • @Steve I don't know why I haven't tried that yet. lol That literally hasn't hit me yet. Thanks! If I wanted to try more complicated signal handling how would I go about this? Would I check the status of the subprocess when it returns? Commented Mar 21, 2019 at 3:49

3 Answers 3

5

What you have in your try/except block is too permissive, such that when Ctrl+C is pressed, the KeyboardInterrupt exception is also handled by that same exception handler as the one that print "Command Failed", and as that is now properly handled there, the flow of the program is continued through the for loop. What you should do is:

  1. Replace except: with except Exception: so that the KeyboardInterrupt exception will not be trapped, such that any time Ctrl+C is pressed the program will terminate (including subprocesses that isn't stuck in some non-terminatable state);
  2. After the print statement, break out of the loop to prevent further execution from happening, if that is the intended behavior that you want this program to do.
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your response. I will try this as well. :) I will be sure to respond with an update.
0

You can catch KeyboardInterrupt, that way you can deal with Ctrl+C in whatever manner you want.

import subprocess
import os
import sys

input_directory = sys.argv[1]

for file in os.listdir(os.path.abspath(input_directory)):
    output = file + "_out.out"
    command = ['somescript.py', file, output]
    try:
        subprocess.check_call(command)
    except KeyboardInterrupt as e:
        print "Interrupted"
        sys.exit(1)
    except:
        print "Command Failed"

However I agree with the other posters in that your exception is too vague, and you should be more specific in what can and can't fail.

Comments

0

I think Ctrl + Z can also help you to push the execution to background and suspended.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.