The first simple answer to the Linux equivalent killall(ProgramName)
The program is to be a toggle program. I can launch Firefox/program.
def tolaunch(program):
os.system("firefox")
When launched I wish to save the name of program launched, in array(simple to do), then launch the program(Firefox)/program.
Here the idea off the toggle come’s in, when Launched and I have finished my browsing, I wish to call the same program(mine), check the array for said program and exit Firefox/program, by running a simple command like killall(“Firefox”) but in Python code. I don’t want to write a long winded command/script, that first has to workout the ‘pid’.
I seem very close to the answer but cant find it.
Edit: people asked for code example | here is my code
# Toggler for macro key -|- many keys = one toggler program
import os
import sys
def startp(program):
# hard-coded
os.system("firefox")
def exitp(program):
# os.close(program)
sys.exit(program)
# Begin
# hard-coded : program start
startp("Firefox")
# loop while program/s active
# exitp("Firefox")
# exit(program) or program end
I tried to include some explanations in way off comments
What you are looking for is the sys.exit() command.
There are 4 functions that exit a program. These are the quit(), exit(), sys.exit() and os._exit(). They have almost same functionality thanks to the fact that they raise the SystemExit exception by which the Python interpreter exits and no stack traceback is printed on the screen.
Among the above four exit functions, sys.exit() is mostly preferred because the exit() and quit() functions cannot be used in production code while os._exit() is for special cases only when an immediate exit is required.
To demonstrate this behavior using the sys.exit() function:
import sys
i=0
while i in range(10):
i += 1
print(i)
if i == 5:
print('I will now exit')
sys.exit()
elif i > 5:
print('I will not run, program alredy exited :(')
I'm working on a piece of code in Python 3 that acts as an interface for various dead by daylight cheats. I'm using a very basic setup, just input() and os.system() to find and open specific files. It works fine, but there's one small issue.
The interface uses cmd prompt, and I have it set up so that entering numbers 1-4 will open programs and executables used to modify the game. However, some of the programs are required to stay open while others run. For example, the BVHR Session Grabber must be running along with the SaveInjector Interface, because the SaveInjector needs to receive a certain code from the Grabber.
There's a problem here, the code is set up in such a way that you can only run one file at a time. I'm not sure what exactly causes this, but I'll try to explain what happens. When entering the number 1, for example, into the cmd prompt window, it opens the BHVR Session Grabber (as intended). After that, the interface becomes unusable until I close the BHVR Session Grabber. I can't type anything into it while it's active, so I can't open multiple programs at once.
Not entirely sure if this is intended or not, but I'm hoping it's avoidable. If anyone has any knowledge on the issue let me know how to find a way around this in the comments please.
import os.path
def interface():
os.system('cls' if os.name == 'nt' else 'clear')
print("""
\n\nSelect a cheat below:
\n
\n1: BHVR Session Grabber
\n2: SaveInjector Interface
\n3: Rank / Shards Editor
\n4: Exit\n
""")
def checker():
interface()
lst = ['1','2','3','4']
good_input = input(">")
global user_input
user_input = None
while not user_input:
if good_input in lst:
user_input = good_input
else:
print("Enter a valid integer.")
good_input = input(">")
checker()
cwd = os.getcwd()
def selection():
if user_input == '1':
f = (os.path.join(cwd, 'Programs', 'BHVRSession', 'CookieFinder.exe'));
os.system(f)
checker()
selection()
elif user_input == '2':
os.system('cmd /k "cd Programs & cd Injector & SI.exe & cd.. & cd.. & Ultimate.py"')
elif user_input == '3':
f = (os.path.join(cwd, 'Programs', 'RankShards', 'Sender.exe'));
os.system(f)
checker()
selection()
elif user_input == '4':
os.system('cmd /k "taskkill/im py.exe"')
selection()
The problem here is that os.system() is blocking. This means that it will only return and continue executing your Python code after the program it runs finishes. Instead, you should look at the subprocess package to learn how to fork a new process that can run in parallel with your Python program.
I am writing a console application which should close every time user type 'exit'. It works only when starting function is called once, otherwise I have to type 'exit' multiple times.
For example: I run the application, type "1", "recipe", "exit" and it works fine. When I type "1", [enter], "2", "exit" - i need to type "exit" one more time... or more (depending on function call times).
Starting function
def start():
running = 'on'
while running == 'on':
recipes.show_recipes()
recipe_choice = input("...")
if recipe_choice == "exit":
running = 'off'
else:
try:
recipes.show_recipes(int(recipe_choice))
except IndexError:
print("...")
start()
except ValueError:
print("...")
start()
response = input("...")
if response == "recipe":
#opening recipe .pdf file
openrecipe(list(list(recipes.recipes.values())[int(recipe_choice)-1].values())[2], shell=True)
start()
elif response == "exit":
running = 'off'
else:
start()
Run program
start()
I suppose that solution is simple but I can't figure out why my application behave like that. I would like to close program any moment I type "exit" in console.
You don't need to call start() over and over - once your program reaches the end of one of it's if clauses, it should start back at the head of the while loop. Otherwise, you're initiating new loops that you have to exit out of manually.
Your function is calling itself recursively, each time pushing a new frame to the call stack and starting a new loop. So if you end up piling say three recursive calls, the first "exit" will exit the last loop, the function execution finishes, the top frame is popped from the stack and the control goes back to the previous stack, so you're back to the second loop, etc (lather, rinse, repeat...)
Recursion is a useful tool when you have to deal with arbitrary nested data structures (trees etc) but it really doesn't belong here - it's both useless (a simple iteration is all you need) and harmful (it keeps on piling on frame after frame eating memory for no good reason and - as you discovered - makes flow control much harder than it has to be).
I'm creating a script and have sucsessfully called on a second one, however, when the second one completes. The program just crashes - is it possible so after the import script section as completed, it will then continue back on the main script.
E.G.
My main one, which is titled Login_MainMenu.py as this script in:
if command == ('caesar'):
import os
os.system('caesarCipher.py')
time.sleep(2)
print("Your task is now completed")
sys.exit()
I'm assuming I'd have to put something at the end of caesarCipher.py, which for now is:
mode = getMode()
message = getMessage()
key = getKey()
print("\nYour translated text is: ")
print(getTranslatedMessage(mode, message, key))
Anyone got any ideas on how to do it?
Thank you.
There's nothing you have to do to return back. If it's crashing, you have a bug somewhere, but since you didn't tell us what the error message was, there's no way to help you.
However, you should not be running your other script via os.system. Import it and call its functions directly.
import caesarCipher
caesarCipher.get_translated_message()
assuming you've put the code into a function called get_translated_message, anyway.
How do I exit a script early, like the die() command in PHP?
import sys
sys.exit()
details from the sys module documentation:
sys.exit([arg])
Exit from Python. This is implemented by raising the
SystemExit exception, so cleanup actions specified by finally clauses
of try statements are honored, and it is possible to intercept the
exit attempt at an outer level.
The optional argument arg can be an integer giving the exit status
(defaulting to zero), or another type of object. If it is an integer,
zero is considered “successful termination” and any nonzero value is
considered “abnormal termination” by shells and the like. Most systems
require it to be in the range 0-127, and produce undefined results
otherwise. Some systems have a convention for assigning specific
meanings to specific exit codes, but these are generally
underdeveloped; Unix programs generally use 2 for command line syntax
errors and 1 for all other kind of errors. If another type of object
is passed, None is equivalent to passing zero, and any other object is
printed to stderr and results in an exit code of 1. In particular,
sys.exit("some error message") is a quick way to exit a program when
an error occurs.
Since exit() ultimately “only” raises an exception, it will only exit
the process when called from the main thread, and the exception is not
intercepted.
Note that this is the 'nice' way to exit. #glyphtwistedmatrix below points out that if you want a 'hard exit', you can use os._exit(*errorcode*), though it's likely os-specific to some extent (it might not take an errorcode under windows, for example), and it definitely is less friendly since it doesn't let the interpreter do any cleanup before the process dies. On the other hand, it does kill the entire process, including all running threads, while sys.exit() (as it says in the docs) only exits if called from the main thread, with no other threads running.
A simple way to terminate a Python script early is to use the built-in quit() function. There is no need to import any library, and it is efficient and simple.
Example:
#do stuff
if this == that:
quit()
Another way is:
raise SystemExit
You can also use simply exit().
Keep in mind that sys.exit(), exit(), quit(), and os._exit(0) kill the Python interpreter. Therefore, if it appears in a script called from another script by execfile(), it stops execution of both scripts.
See "Stop execution of a script called with execfile" to avoid this.
While you should generally prefer sys.exit because it is more "friendly" to other code, all it actually does is raise an exception.
If you are sure that you need to exit a process immediately, and you might be inside of some exception handler which would catch SystemExit, there is another function - os._exit - which terminates immediately at the C level and does not perform any of the normal tear-down of the interpreter; for example, hooks registered with the "atexit" module are not executed.
I've just found out that when writing a multithreadded app, raise SystemExit and sys.exit() both kills only the running thread. On the other hand, os._exit() exits the whole process. This was discussed in "Why does sys.exit() not exit when called inside a thread in Python?".
The example below has 2 threads. Kenny and Cartman. Cartman is supposed to live forever, but Kenny is called recursively and should die after 3 seconds. (recursive calling is not the best way, but I had other reasons)
If we also want Cartman to die when Kenny dies, Kenny should go away with os._exit, otherwise, only Kenny will die and Cartman will live forever.
import threading
import time
import sys
import os
def kenny(num=0):
if num > 3:
# print("Kenny dies now...")
# raise SystemExit #Kenny will die, but Cartman will live forever
# sys.exit(1) #Same as above
print("Kenny dies and also kills Cartman!")
os._exit(1)
while True:
print("Kenny lives: {0}".format(num))
time.sleep(1)
num += 1
kenny(num)
def cartman():
i = 0
while True:
print("Cartman lives: {0}".format(i))
i += 1
time.sleep(1)
if __name__ == '__main__':
daemon_kenny = threading.Thread(name='kenny', target=kenny)
daemon_cartman = threading.Thread(name='cartman', target=cartman)
daemon_kenny.setDaemon(True)
daemon_cartman.setDaemon(True)
daemon_kenny.start()
daemon_cartman.start()
daemon_kenny.join()
daemon_cartman.join()
from sys import exit
exit()
As a parameter you can pass an exit code, which will be returned to OS. Default is 0.
I'm a total novice but surely this is cleaner and more controlled
def main():
try:
Answer = 1/0
print Answer
except:
print 'Program terminated'
return
print 'You wont see this'
if __name__ == '__main__':
main()
...
Program terminated
than
import sys
def main():
try:
Answer = 1/0
print Answer
except:
print 'Program terminated'
sys.exit()
print 'You wont see this'
if __name__ == '__main__':
main()
...
Program terminated Traceback (most recent call last): File "Z:\Directory\testdieprogram.py", line 12, in
main() File "Z:\Directory\testdieprogram.py", line 8, in main
sys.exit() SystemExit
Edit
The point being that the program ends smoothly and peacefully, rather than "I'VE STOPPED !!!!"
Problem
In my practice, there was even a case when it was necessary to kill an entire multiprocessor application from one of those processes.
The following functions work well if your application uses the only main process. But no one of the following functions didn't work in my case as the application had many other alive processes.
quit()
exit(0)
os._exit(0)
sys.exit(0)
os.kill(os.getppid(), 9) - where os.getppid() is the pid of parent process
The last one killed the main process and itself but the rest processes were still alive.
Solution
I had to kill it by external command and finally found the solution using pkill.
import os
# This can be called even in process worker and will kill
# whole application included correlated processes as well
os.system(f"pkill -f {os.path.basename(__file__)}")
In Python 3.5, I tried to incorporate similar code without use of modules (e.g. sys, Biopy) other than what's built-in to stop the script and print an error message to my users. Here's my example:
## My example:
if "ATG" in my_DNA:
## <Do something & proceed...>
else:
print("Start codon is missing! Check your DNA sequence!")
exit() ## as most folks said above
Later on, I found it is more succinct to just throw an error:
## My example revised:
if "ATG" in my_DNA:
## <Do something & proceed...>
else:
raise ValueError("Start codon is missing! Check your DNA sequence!")
My two cents.
Python 3.8.1, Windows 10, 64-bit.
sys.exit() does not work directly for me.
I have several nexted loops.
First I declare a boolean variable, which I call immediateExit.
So, in the beginning of the program code I write:
immediateExit = False
Then, starting from the most inner (nested) loop exception, I write:
immediateExit = True
sys.exit('CSV file corrupted 0.')
Then I go into the immediate continuation of the outer loop, and before anything else being executed by the code, I write:
if immediateExit:
sys.exit('CSV file corrupted 1.')
Depending on the complexity, sometimes the above statement needs to be repeated also in except sections, etc.
if immediateExit:
sys.exit('CSV file corrupted 1.5.')
The custom message is for my personal debugging, as well, as the numbers are for the same purpose - to see where the script really exits.
'CSV file corrupted 1.5.'
In my particular case I am processing a CSV file, which I do not want the software to touch, if the software detects it is corrupted. Therefore for me it is very important to exit the whole Python script immediately after detecting the possible corruption.
And following the gradual sys.exit-ing from all the loops I manage to do it.
Full code: (some changes were needed because it is proprietory code for internal tasks):
immediateExit = False
start_date = '1994.01.01'
end_date = '1994.01.04'
resumedDate = end_date
end_date_in_working_days = False
while not end_date_in_working_days:
try:
end_day_position = working_days.index(end_date)
end_date_in_working_days = True
except ValueError: # try statement from end_date in workdays check
print(current_date_and_time())
end_date = input('>> {} is not in the list of working days. Change the date (YYYY.MM.DD): '.format(end_date))
print('New end date: ', end_date, '\n')
continue
csv_filename = 'test.csv'
csv_headers = 'date,rate,brand\n' # not real headers, this is just for example
try:
with open(csv_filename, 'r') as file:
print('***\nOld file {} found. Resuming the file by re-processing the last date lines.\nThey shall be deleted and re-processed.\n***\n'.format(csv_filename))
last_line = file.readlines()[-1]
start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
resumedDate = start_date
if last_line == csv_headers:
pass
elif start_date not in working_days:
print('***\n\n{} file might be corrupted. Erase or edit the file to continue.\n***'.format(csv_filename))
immediateExit = True
sys.exit('CSV file corrupted 0.')
else:
start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
print('\nLast date:', start_date)
file.seek(0) # setting the cursor at the beginnning of the file
lines = file.readlines() # reading the file contents into a list
count = 0 # nr. of lines with last date
for line in lines: #cycling through the lines of the file
if line.split(',')[0] == start_date: # cycle for counting the lines with last date in it.
count = count + 1
if immediateExit:
sys.exit('CSV file corrupted 1.')
for iter in range(count): # removing the lines with last date
lines.pop()
print('\n{} lines removed from date: {} in {} file'.format(count, start_date, csv_filename))
if immediateExit:
sys.exit('CSV file corrupted 1.2.')
with open(csv_filename, 'w') as file:
print('\nFile', csv_filename, 'open for writing')
file.writelines(lines)
print('\nRemoving', count, 'lines from', csv_filename)
fileExists = True
except:
if immediateExit:
sys.exit('CSV file corrupted 1.5.')
with open(csv_filename, 'w') as file:
file.write(csv_headers)
fileExists = False
if immediateExit:
sys.exit('CSV file corrupted 2.')
Just put at the end of your code quit() and that should close a python script.
In Python 3.9, you can also use: raise SystemExit("Because I said so").
use exit and quit in .py files
and sys.exit for exe files