Killing a process within a python script running on linux - python

I have Raspbian as the linux distro running on my RPI. I've setup a small socket server using twisted and it receives certain commands from an iOS app. These commands are strings. I started a process when I received "st" and now I want to kill it when i get "sp". This is the way I tried:
Imported OS
Used os.system("...") //to start process
os.system("...") // to kill process
Lets say the service is named xyz.
This is the exact way I tried to kill it:
os.system('ps axf | grep xyz | grep -v grep | awk '{print "kill " $1 }' | sh')
But I got a syntax error. That line runs perfectly when I try it in terminal separately. Is this a wrong way to do this in a python script? How do I fix it?

You will need to escape the quotes in your string:
os.system('ps axf | grep xyz | grep -v grep | awk \'{print "kill " $1 }\' | sh')
Or use a triple quote:
os.system('''ps axf | grep xyz | grep -v grep | awk '{print "kill " $1 }' | sh''')

Alternatively, open the process with Popen(...).pid and then use os.kill()
my_pid = Popen('/home/rolf/test1.sh',).pid
os.kill(int(my_pid), signal.SIGKILL)
Remember to include a shebang in your script (#!/bin/sh)
Edit:
On second thoughts, perhaps
os.kill(int(my_pid), signal.SIGTERM)
is probably a better way to end the process, it at least gives the process the chance to close down gracefully.

Related

Kill SimpleHTTPServer process which is started in background with subprocess.Popen

I am trying to kill SimpleHTTPServer in my script.
Manually the command is working fine.
Starting SimpleHTTPServer in background:
-bash-4.2$ python -m SimpleHTTPServer 8080 &
[1] 26345
Verifying SimpleHTTPServer process:
-bash-4.2$ ps -ef | grep SimpleHTTPServer
x 26345 20169 0 17:44 pts/21 00:00:00 python -m SimpleHTTPServer 8080
Killing SimpleHTTPServer:
-bash-4.2$ kill -9 `ps -ef | grep SimpleHTTPServer | grep 8080 | awk '{print $2}'`
Verifying SimpleHTTPServer is killed or not:
-bash-4.2$ ps -ef | grep SimpleHTTPServer
x 26356 20169 0 17:45 pts/21 00:00:00 grep --color=auto SimpleHTTPServer
Same thing in script is not working. I am using subprocess.Popen.
subprocess.Popen(["kill", "-9", "`ps -ef | grep SimpleHTTPServer | grep 8080 | awk '{print $2}'`"])
(Pdb++) kill: cannot find process "`ps -ef | grep SimpleHTTPServer | grep 8080 | awk '{print $2}'`"
You're trying to use a shell backtick, around a shell pipeline, in that kill command. But you're trying to do it without shell=True. You can't do that.
You can build a sh command line and run that with shell=True, but that's usually a bad idea.
The subprocess docs on Replacing Older Functions with the subprocess Module show how you can do the same things in Python that you were using the shell for. That's a better idea, but a bit of work.
But the simplest thing to do is just not call any of this stuff.
You don't need the ps|grep|grep|awk to find the PID of the process, because you Popened the process, so it's just proc.pid.
And you don't need the kill either, because you still have that Popen object around, so you can just call kill, terminate, or send_signal on it.

Execute complex bash script within Python

I have a bash script which I run on my .csv file and then I run python script on the output of bash script. I would like to make everything into a single script, but bash scrip is quite complex and I couldn't find a way to use it in a Python..
grep "$(grep -E "tcp|udp" results.csv | grep -E "Critical|High|Medium" | awk -F "\"*,\"*" '{print $8}')" results.csv | sort -t',' -k4,4 -k8,8 | awk -F "\"*,\"*" '{print $5,"port",$7"/"$6,$8}' | sed '/tcp\|udp/!d' | awk '!a[$0]++' | sed '/,port,\/,/d' > out
I tried this both as a string, and as a parametrized command with subprocess, however it's just seems way too many complex characters for everything to work.
Is there a way simpler way to run this command in Python?
P.S. I know there are multiple questions & answers regarding this same topic, but none of them worked for me.
Could you please escape all the " double quotes" with \ please try it out and let us know if it worked:
os.system(" grep \"$(grep -E \"tcp|udp\" results.csv | grep -E \"Critical|High|Medium\" | awk -F \"\\\"*,\\\"*\" '{print $8}')\" results.csv | sort -t',' -k4,4 -k8,8 | awk -F \"\\\"*,\\\"*\" '{print $5,\"port\",$7\"/\"$6,$8}' | sed '/tcp\|udp/!d' | awk '!a[$0]++' | sed '/,port,\/,/d' > out ")
The whole command can be put into " your_command_with\"escaped\"double quotes ".
Have a nice day

Kill python interpeter in linux from the terminal

I want to kill python interpeter - The intention is that all the python files that are running in this moment will stop (without any informantion about this files).
obviously the processes should be closed.
Any idea as delete files in python or destroy the interpeter is ok :D (I am working with virtual machine).
I need it from the terminal because i write c code and i use linux commands...
Hope for help
pkill -9 python
should kill any running python process.
There's a rather crude way of doing this, but be careful because first, this relies on python interpreter process identifying themselves as python, and second, it has the concomitant effect of also killing any other processes identified by that name.
In short, you can kill all python interpreters by typing this into your shell (make sure you read the caveats above!):
ps aux | grep python | grep -v "grep python" | awk '{print $2}' | xargs kill -9
To break this down, this is how it works. The first bit, ps aux | grep python | grep -v "grep python", gets the list of all processes calling themselves python, with the grep -v making sure that the grep command you just ran isn't also included in the output. Next, we use awk to get the second column of the output, which has the process ID's. Finally, these processes are all (rather unceremoniously) killed by supplying each of them with kill -9.
pkill with script path
pkill -9 -f path/to/my_script.py
is a short and selective method that is more likely to only kill the interpreter running a given script.
See also: https://unix.stackexchange.com/questions/31107/linux-kill-process-based-on-arguments
You can try the killall command:
killall python
pgrep -f <your process name> | xargs kill -9
This will kill the your process service.
In my case it is
pgrep -f python | xargs kill -9
pgrep -f youAppFile.py | xargs kill -9
pgrep returns the PID of the specific file will only kill the specific application.
If you want to show the name of processes and kill them by the command of the kill, I recommended using this script to kill all python3 running process and set your ram memory free :
ps auxww | grep 'python3' | awk '{print $2}' | xargs kill -9
to kill python script while using ubuntu 20.04.2 intead of Ctrl + C just push together
Ctrl + D
I have seen the pkill command as the top answer. While that is all great, I still try to tread carefully (since, I might be risking my machine whilst killing processes) and follow the below approach:
First list all the python processes using:
$ ps -ef | grep python
Just to have a look at what root user processes were running beforehand and to cross-check later, if they are still running (after I'm done! :D)
then using pgrep as :
$ pgrep -u <username> python -d ' ' #this gets me all the python processes running for user username
# eg output:
11265 11457 11722 11723 11724 11725
And finally, I kill these processes by using the kill command after cross-checking with the output of ps -ef| ...
kill -9 PID1 PID2 PID3 ...
# example
kill -9 11265 11457 11722 11723 11724 11725
Also, we can cross check the root PIDs by using :
pgrep -u root python -d ' '
and verifying with the output from ps -ef| ...

How to kill multiple tornado processes at one time?

I used nohup python *.py & to run my tornado web service, and 8 processes started.
.
However, it is really annoying killing my tornado processes. I have to ues kill -3 pid 8 times to finally turn down my service. So I want to know how can I kill the 8 processes at one time in my bash? Thanks.
I tried killall python, but it is dangerous when there is other python process running.
#Viktor suggest me to use pkill -P <parent> and it works in my Ubuntu. But in Centos, 'pkill' doesn't work. So how can I 'pkill' the processes in Centos? Thanks.
This depends on your environment a bit.
But you may want to look into pkill -P <parent>, which kills everything with the same parent pid.
Maybe :
ps aux | grep -e 'python spam.py' | grep -v grep | awk '{print $2}' | xargs -i kill {}
Killing the parent process, that is the one with smallest PID should do the job, like kill -15 18054 in your ps example. Also, you could do some grep magic, like:
for i in `ps waux | grep "python spam.py" | awk '{ print $2 }'`; do kill -15 ${i}; done

Grepping using shell - long delay

I have a benchmark thread running and it takes a couple of hours to run.
The script for initiating the benchmark thread was done using python.
It prints out some random "foo" and I want to grep it for further use.
So, I wrote a shell script that does this.
#!/bin/bash
id = `taskset -c 0 python <path>/run-apps.py <thread> | grep "pid" | awk '{print $2}'`
echo $id
Since, the thread takes a very long time.
Maybe the shell script is unable to jump to the next line till the execution is over and I am unable to print the id as soon as it initiates it..
do you see any problem? or how I can rectify this?
This statement
echo $id
cannot run until the previous statement
id=`taskset -c 0 python <path>/run-apps.py <thread> | grep "pid" | awk '{print $2}'`
completes. If you don't need $id, get rid of it and simply run
taskset -c 0 python <path>/run-apps.py <thread> | grep "pid" | awk '{print $2}'
to see the output as it is generated (but you may need to disable buffering, as pointed out by Martijn). If you do need $id, you can use the tee command
to store a copy of the output and print it to standard error at the same time:
id=$(taskset -c 0 python <path>/run-apps.py <thread> |\
grep "pid" | awk '{print $2}' | tee /dev/stderr) # Or some other file descriptor that goes to your terminal
A third option is to use a temporary file.
taskset -c 0 python <path>/run-apps.py <thread> | grep "pid" | awk '{print $2}' > tmpfile &
tail --pid $! -f tmpfile # Watch tmpfile until the backgrounded job completes
do-other-job --reading-from tmpfile

Categories