CodyChan
CodyChan

Reputation: 1865

How to show Window title of GUI applications in terminal in Linux

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

Answers (1)

CodyChan
CodyChan

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

Related Questions