Sending SIGINT (Ctrl-C) to program running in Eclipse Console - python

I have setup a run configuration in Eclipse and need to send SIGINT (Ctrl+C) to the program. There is cleanup code in the program that runs after SIGINT, so pressing Eclipse's "Terminate" buttons won't work (they send SIGKILL I think). Typing CTRL+C into the Console also doesn't work.
How do I send SIGINT to a process running inside an Eclipse Console?
(FWIW I am running a Twisted daemon and need Twisted to shutdown correctly, which only occurs on SIGINT)

If you can determine the process with a utility such as ps, you can use kill to send it a SIGINT. The program will likely be a child process of eclipse.
kill -s INT <pid>

You can send the command via one line:
kill -SIGINT $(ps aux | grep ProgrammName | grep -v grep | awk '{print $2}')
Get the process id and than send the sigint signal

That still seems to be an open issue:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=38016
Just for the sake of completeness: If you came here to find a way to terminate a read line from System.in,
Ctrl + Z worked for me (on Windows).

in some versions, you can do the following.
In the Debug perspective, you can open a view called "Signals"
(Window/Show View/Signals" or Left-Bottom Icon).
You will get a list of all supported signals. Right-click and "Resume
with Signal" will give you the result you need.

I'm making an answer out of a modification of Artur Czajka's comment.
You can use pkill -SIGINT -f ProgramName. Explanation: pkill is similar to killall, -SIGINT states the signal to be used, -f makes it work better in this case (it will look through arguments and stuff instead of just the command name), and ProgramName is the target for pkill.

Related

continue program even after logout [duplicate]

I have Python script bgservice.py and I want it to run all the time, because it is part of the web service I build. How can I make it run continuously even after I logout SSH?
Run nohup python bgservice.py & to get the script to ignore the hangup signal and keep running. Output will be put in nohup.out.
Ideally, you'd run your script with something like supervise so that it can be restarted if (when) it dies.
If you've already started the process, and don't want to kill it and restart under nohup, you can send it to the background, then disown it.
Ctrl+Z (suspend the process)
bg (restart the process in the background
disown %1 (assuming this is job #1, use jobs to determine)
Running a Python Script in the Background
First, you need to add a shebang line in the Python script which looks like the following:
#!/usr/bin/env python3
This path is necessary if you have multiple versions of Python installed and /usr/bin/env will ensure that the first Python interpreter in your $$PATH environment variable is taken. You can also hardcode the path of your Python interpreter (e.g. #!/usr/bin/python3), but this is not flexible and not portable on other machines. Next, you’ll need to set the permissions of the file to allow execution:
chmod +x test.py
Now you can run the script with nohup which ignores the hangup signal. This means that you can close the terminal without stopping the execution. Also, don’t forget to add & so the script runs in the background:
nohup /path/to/test.py &
If you did not add a shebang to the file you can instead run the script with this command:
nohup python /path/to/test.py &
The output will be saved in the nohup.out file, unless you specify the output file like here:
nohup /path/to/test.py > output.log &
nohup python /path/to/test.py > output.log &
If you have redirected the output of the command somewhere else - including /dev/null - that's where it goes instead.
# doesn't create nohup.out
nohup command >/dev/null 2>&1
If you're using nohup, that probably means you want to run the command in the background by putting another & on the end of the whole thing:
# runs in background, still doesn't create nohup.out
nohup command >/dev/null 2>&1 &
You can find the process and its process ID with this command:
ps ax | grep test.py
# or
# list of running processes Python
ps -fA | grep python
ps stands for process status
If you want to stop the execution, you can kill it with the kill command:
kill PID
You could also use GNU screen which just about every Linux/Unix system should have.
If you are on Ubuntu/Debian, its enhanced variant byobu is rather nice too.
You might consider turning your python script into a proper python daemon, as described here.
python-daemon is a good tool that can be used to run python scripts as a background daemon process rather than a forever running script. You will need to modify existing code a bit but its plain and simple.
If you are facing problems with python-daemon, there is another utility supervisor that will do the same for you, but in this case you wont have to write any code (or modify existing) as this is a out of the box solution for daemonizing processes.
Alternate answer: tmux
ssh into the remote machine
type tmux into cmd
start the process you want inside the tmux e.g. python3 main.py
leaving the tmux session by Ctrl+b then d
It is now safe to exit the remote machine. When you come back use tmux attach to re-enter tmux session.
If you want to start multiple sessions, name each session using Ctrl+b then $. then type your session name.
to list all session use tmux list-sessions
to attach a running session use tmux attach-session -t <session-name>.
You can nohup it, but I prefer screen.
Here is a simple solution inside python using a decorator:
import os, time
def daemon(func):
def wrapper(*args, **kwargs):
if os.fork(): return
func(*args, **kwargs)
os._exit(os.EX_OK)
return wrapper
#daemon
def my_func(count=10):
for i in range(0,count):
print('parent pid: %d' % os.getppid())
time.sleep(1)
my_func(count=10)
#still in parent thread
time.sleep(2)
#after 2 seconds the function my_func lives on is own
You can of course replace the content of your bgservice.py file in place of my_func.
Try this:
nohup python -u <your file name>.py >> <your log file>.log &
You can run above command in screen and come out of screen.
Now you can tail logs of your python script by: tail -f <your log file>.log
To kill you script, you can use ps -aux and kill commands.
The zsh shell has an option to make all background processes run with nohup.
In ~/.zshrc add the lines:
setopt nocheckjobs #don't warn about bg processes on exit
setopt nohup #don't kill bg processes on exit
Then you just need to run a process like so: python bgservice.py &, and you no longer need to use the nohup command.
I know not many people use zsh, but it's a really cool shell which I would recommend.
If what you need is that the process should run forever no matter whether you are logged in or not, consider running the process as a daemon.
supervisord is a great out of the box solution that can be used to daemonize any process. It has another controlling utility supervisorctl that can be used to monitor processes that are being run by supervisor.
You don't have to write any extra code or modify existing scripts to make this work. Moreover, verbose documentation makes this process much simpler.
After scratching my head for hours around python-daemon, supervisor is the solution that worked for me in minutes.
Hope this helps someone trying to make python-daemon work
You can also use Yapdi:
Basic usage:
import yapdi
daemon = yapdi.Daemon()
retcode = daemon.daemonize()
# This would run in daemon mode; output is not visible
if retcode == yapdi.OPERATION_SUCCESSFUL:
print('Hello Daemon')

How to run nohup command from Python script?

I have a simple question. I have tried to search for a solution but there are no answers which would explain what I need.
The question is:
How do I start a nohup command from Python? Basically the idea is, that I have a Python script which prepares my environment and I need it to launch multiple scripts with nohup commands. How do I start a nohup command like nohup python3 my_script.py & from within a running Python script to have that nohup command running even after I log out?
Thank you
You do not need nohup -- not even in shell, and even less so in Python. It does the following things:
Configures the HUP signal to be ignored (rarely relevant: if a process has no handles on a TTY it isn't going to be notified when that TTY exits regardless; the shell only propagates signals to children in interactive mode, not when running scripts).
If stdout is a terminal, redirects it to nohup.out
If stderr is a terminal, redirects it to wherever stdout was already redirected.
Redirects stdin to /dev/null
That's it. There's no reason to use nohup to do any of those things; they're all trivial to do without it:
</dev/null redirects stdin from /dev/null in shell; stdin=subprocess.DEVNULL does so in Python.
>nohup.out redirects stdout to nohup.out in shell; stdout=open('nohup.out', 'w') does so in Python.
2>&1 makes stderr go to the same place as stdout in shell; stderr=subprocess.STDOUT does so in Python.
Because your process isn't attached to the terminal by virtue of the above redirections, it won't implicitly get a HUP when that terminal closes. If you're worried about a signal being sent to the parent's entire process group, however, you can avoid that by splitting off the child into a separate one:
The subprocess.Popen argument start_new_session=True splits the child process into a separate group from the parent in Python, so a parent sent to the process group of the parent as a whole will not be received by the child.
Adding a preexec_fn with signal.signal(signal.SIGHUP, signal.SIG_IGN) is even more explicit that the child should by default ignore a SIGHUP even if one is received.
Putting this all together might look like (if you really do want logs to go to a file named nohup.out -- I would suggest picking a better name):
import subprocess, signal
subprocess.Popen(['python3', 'my_script.py'],
stdin=subprocess.DEVNULL,
stdout=open('nohup.out', 'w'),
stderr=subprocess.STDOUT,
start_new_session=True,
preexec_fn=(lambda: signal.signal(signal.SIGHUP, signal.SIG_IGN)))

Python: How do I send a SIGINT signal to program opened with 'xterm -e ...'?

I am trying to use Python to send a SIGINT signal to a process created through subprocess.Popen. I need to run test.bash and have it open in a new window, then wait 4 seconds, send SIGINT (the equivalent of using Ctrl-C) so I am using the following code:
command = "xterm -e bash test.bash"
process = subprocess.Popen(command.split())
time.sleep(4)
os.kill(process.pid, signal.SIGINT)
I have "test.bash" set up to trap the SIGINT signal, and run a cleanup command. This works when I run "test.bash" straight from the command line. But when I send it through xterm -e bash test.bash in Python it instantly terminates the process entirely and does not handle the SIGINT signal at all.
I've tried some things I've read online about killing the process group, but that's not doing anything either. I tried replacing os.kill(process.pid, signal.SIGINT) with process.send_signal(signal.SIGINT) to no avail. Any ideas?
You probably need to add the -hold option to xterm, i.e. xterm -hold -e... to prevent it from closing after the bash script completes since you're using sleep in python rather than the shell.
If you're unable to get the right PID, replacing the second line with this might work:
cmd = "pgrep -f 'xterm -e bash test.bash'"
id = subprocess.check_output(cmd, shell=True)
Then use id instead of process.pid

Find Windows PID of a python script with Windows Command Prompt

I am running two different python scripts running on a windows machine simultaneously and would like to kill one but not the other from the command prompt. Using taskkill with the name "python.exe" does not allow me to choose to kill just one of these scripts.
Is there a way in windows to kill just one of these tasks, determined by the script from which it originated?
For example: if I run python_process1.py and python_process2.py and would like to kill the .exe associated with just python_process2.py and leave python_process1.py alone.
UPDATE: the solution below does not kill the process, and the issue still lies in identifying the PID of a process by python script name. If this is impossible, is there a way to selectively kill python scripts on windows that I am unaware of?
Thank you.
Using Get-WmiObject and PowerShell you can examine the command line arguments for each process, then pass the selected Process ID to taskkill.
This example shows how to kill a process executing the script test.py:
PS C:\Users\Administrator> taskkill.exe /F /PID $(Get-WmiObject Win32_Process -Filter "name = 'python.exe'" | Where-Object {$_.CommandLine -like '*.\test.py'} | Select -ExpandProperty ProcessId)
Modify *.\test.py to match how you are actually calling each script, and it should work for you

How to stop/terminate a python script from running?

I wrote a program in IDLE to tokenize text files and it starts to tokeniza 349 text files! How can I stop it? How can I stop a running Python program?
You can also do it if you use the exit() function in your code. More ideally, you can do sys.exit(). sys.exit() which might terminate Python even if you are running things in parallel through the multiprocessing package.
Note: In order to use the sys.exit(), you must import it: import sys
To stop your program, just press Control + C.
If your program is running at an interactive console, pressing CTRL + C will raise a KeyboardInterrupt exception on the main thread.
If your Python program doesn't catch it, the KeyboardInterrupt will cause Python to exit. However, an except KeyboardInterrupt: block, or something like a bare except:, will prevent this mechanism from actually stopping the script from running.
Sometimes if KeyboardInterrupt is not working you can send a SIGBREAK signal instead; on Windows, CTRL + Pause/Break may be handled by the interpreter without generating a catchable KeyboardInterrupt exception.
However, these mechanisms mainly only work if the Python interpreter is running and responding to operating system events. If the Python interpreter is not responding for some reason, the most effective way is to terminate the entire operating system process that is running the interpreter. The mechanism for this varies by operating system.
In a Unix-style shell environment, you can press CTRL + Z to suspend whatever process is currently controlling the console. Once you get the shell prompt back, you can use jobs to list suspended jobs, and you can kill the first suspended job with kill %1. (If you want to start it running again, you can continue the job in the foreground by using fg %1; read your shell's manual on job control for more information.)
Alternatively, in a Unix or Unix-like environment, you can find the Python process's PID (process identifier) and kill it by PID. Use something like ps aux | grep python to find which Python processes are running, and then use kill <pid> to send a SIGTERM signal.
The kill command on Unix sends SIGTERM by default, and a Python program can install a signal handler for SIGTERM using the signal module. In theory, any signal handler for SIGTERM should shut down the process gracefully. But sometimes if the process is stuck (for example, blocked in an uninterruptable IO sleep state), a SIGTERM signal has no effect because the process can't even wake up to handle it.
To forcibly kill a process that isn't responding to signals, you need to send the SIGKILL signal, sometimes referred to as kill -9 because 9 is the numeric value of the SIGKILL constant. From the command line, you can use kill -KILL <pid> (or kill -9 <pid> for short) to send a SIGKILL and stop the process running immediately.
On Windows, you don't have the Unix system of process signals, but you can forcibly terminate a running process by using the TerminateProcess function. Interactively, the easiest way to do this is to open Task Manager, find the python.exe process that corresponds to your program, and click the "End Process" button. You can also use the taskkill command for similar purposes.
To stop a python script just press Ctrl + C.
Inside a script with exit(), you can do it.
You can do it in an interactive script with just exit.
You can use pkill -f name-of-the-python-script.
To stop a python script using the keyboard: Ctrl + C
To stop it using code (This has worked for me on Python 3) :
import os
os._exit(0)
you can also use:
import sys
sys.exit()
or:
exit()
or:
raise SystemExit
To stop a running program, use Ctrl+C to terminate the process.
To handle it programmatically in python, import the sys module and use sys.exit() where you want to terminate the program.
import sys
sys.exit()
Ctrl-Break it is more powerful than Ctrl-C
When I have a python script running on a linux terminal, CTRL+\ works. (not CRTL + C or D)
Ctrl+Z should do it, if you're caught in the python shell. Keep in mind that instances of the script could continue running in background, so under linux you have to kill the corresponding process.
exit() will kill the Kernel if you're in Jupyter Notebook so it's not a good idea. raise command will stop the program.
To stop your program, just press CTRL + D
or exit().
you can also use the Activity Monitor to stop the py process
Control+D works for me on Windows 10. Also, putting exit() at the end also works.
Windows solution: Control + C.
Macbook solution: Control (^) + C.
Another way is to open a terminal, type top, write down the PID of the process that you would like to kill and then type on the terminal: kill -9 <pid>
If you are working with Spyder, use CTRL+. and you will restart the kernel, also you will stop the program.
Try using:
Ctrl + Fn + S
or
Ctrl + Fn + B
Press Ctrl+Alt+Delete and Task Manager will pop up. Find the Python command running, right click on it and and click Stop or Kill.
If you are writing a script to process 349 files, but want to test with fewer, just write a nonexisting word like 'stop' in your list, which will cause a stop in the form of an exception. This avoids dialogs like do you want to kill your process if you use exit() or quit()

Categories

Resources