Reputation: 1865
I defined an interactive function called pk
in my shell script to kill programs, such as pk emacs
to kill emacs programs, but if multiple instances are running, then ask you to choose the pid to kill or kill them all.
This happens occasionally when one of my Emacs freezes since my CentOS in my company is old, but in my script function pk
, I use ps
to filter the commands and their PIDs, AFAIK ps
tells no window title in this case, it just prints one or more "/usr/bin/emacs", no more details, and I don't know which PID freezes or no-response which I am going to kill.
I know I can use system tools like System Activity
(KDE) to check the window title and kill the program, but I want to kill program in terminal using pk
function, so is there any tool like ps
but showing "window-title + command + pid" so I can use in my script to kill that program.
Since if you open a file using vim or emacs from terminal, ps
with options will show the file it is editing, so I know the details of the PID and know which one to kill, so here, the Window title is like the Window title in System Activity
.
Of course, if getting the Widow title is the wrong way, if anyone knows how to kill one of multiple instances of the same program just like I said, the answers would be welcome.
Upvotes: 2
Views: 583
Reputation: 1865
I just found another solution I can use in my pk
function to kill the frozen emacs with the following line:
kill -SIGUSR2 (xprop | grep -i pid | grep -Po "[0-9]+")
The (xprop...)
part will return the PID when you click on a GUI program using your mouse.
If anyone is interesting in my pk
function, here it is(NOTE that I'm using fish-shell, so this is fish script function):
function pk --description 'kill processes containg a pattern'
set done 1
set result (psg $argv[1] | wc -l)
if test $result = 0
echo "No '$argv[1]' process is running!"
else if test $result = 1
psg $argv[1] | awk '{print $2}' | xargs kill -9
if test $status = 123 # Operation not permitted
read -p 'echo "Use sudo to kill it? [y/N]: "' -l arg
if test "$arg" = "y"
psg $argv[1] | awk '{print $2}' | xargs sudo kill -9
end
end
else
psg $argv[1]
while test $done = 1
read -p 'echo "Kill all of them or specific PID? [y/N/pid]: "' -l arg
if test "$arg" = "y"
psg $argv[1] | awk '{print $2}' | xargs kill -9
if test $status -eq 123 # Operation not permitted
read -p 'echo "Use sudo to kill them all? [y/N]: "' -l arg2
if test "$arg2" = "y"
psg $argv[1] | awk '{print $2}' | xargs sudo kill -9
end
end
set done 0
else if test $arg -a "$arg" != "y" -a "$arg" != "n"
# the fist cond in test means you typed something, RET will not pass
if test (psg $argv[1] | awk '{print $2}' | grep -i $arg)
kill -9 $arg #2>/dev/null
if test $status -eq 1 # kill failed
read -p 'echo "Use sudo to kill it? [y/N]: "' -l arg2
if test "$arg2" = "y"
sudo kill -9 $arg
end
end
echo -e "Continue...\n"
usleep 100000
psg $argv[1]
else if test "$arg" = "p"
# This may be used for frozen emacs specifically, -usr2 or -SIGUSR2
# will turn on `toggle-debug-on-quit`, turn it off once emacs is alive again
# Test on next frozen Emacs
kill -SIGUSR2 (xprop | grep -i pid | grep -Po "[0-9]+")
# kill -usr2 (xprop | grep -i pid | grep -Po "[0-9]+")
return
else
echo "PID '$arg[1]' is not in the list!"
echo
end
set done 1
else
# RET goes here, means `quit` like C-c
set done 0
end
end
end
end
Upvotes: 1