Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I usually use long running X sessions with several virtual desktops and many many xterms.

I also use job control in the shell (zsh).

Sometimes I wish I could identify an xterm a shell or process is running in (or even suspended in) with a simple command.

For example, you edit a file with vim and vim warns you that it is already opened with another vim instance which is still running. But now you have forgotten in which xterm this vim with process-id XYZ was started and suspended. Killing it does not work, because it is suspended. Resuming it via a signal and then killing could work, but it may screw up an in-foreground running process and perhaps you don't want to kill the vim instance because it has several windows set up ...

Currently I am using awesomewm, but I am also interested in solutions for other wms.

share|improve this question

2 Answers 2

up vote 6 down vote accepted

Xterm puts the variable WINDOWID in the environment of its subprocess. Its value is the window ID of the xterm window. There is no POSIX way of querying the environment of a process based on its PID; here's a Linux way of querying the environment of process $pid and extracting the WINDOWID variable:

</proc/$pid/environ gawk -v 'RS=\0' -F = '$1=="WINDOWID" {print $2}'

You can then find or act on the window with wmctrl or through your window manager's interface.

If you use screen, first try the STY variable, which is set to the name of the screen session. You can connect to that session with screen -rd -S "$sessionname".

share|improve this answer
    
That will only work with gawk. mawk (the default on Debian and possibly Ubuntu) does not handle a NUL record separator. Another way to extract the environment of a process is xargs -n 1 -0 < /proc/$PID/environ –  camh Oct 16 '10 at 23:54
    
@camh: Thanks. (More precisely, /usr/bin/awk is gawk by default on Debian and Ubuntu but only if you've installed gawk or one of its few dependencies.) Another way of parsing /proc/$PID/environ is to tr '\n\0' '\n\0' | sed -ne 's/^WINDOWID=//p' (it's even POSIX, but that's moot since the input file isn't). –  Gilles Oct 17 '10 at 0:26

You can use ps -o ppid= PID to get the parent ID of process PID, which will probably be the shell that launched it. The parent ID of that shell will be the terminal containing it.


To test, I spawned a process that would stay around for a while:

$ sleep 5m &
[1] 31177

Then I looked up the parent of process 31177, and what command it is:

$ ps -o ppid= 31177
31107
$ ps -o cmd= 31107
zsh

31107 is the zsh process I ran the sleep 5m in. I repeated that on the zsh process

$ ps -o ppid= 31107
31097
$ ps -o cmd= 31097
xterm

31097 is the xterm that my zsh shell was running in


If you're not sure how far up the parent you want is, you can use this to search for a parent with the given command name:

pid="$1"
cmd="$2"

seek=""
while [ "$seek" != "$cmd" ]; do
    # ps -o ppid= $pid
    pid=`ps -o ppid= $pid`
    seek=`ps -o cmd= $pid`

    if [ ${pid/ /} = 1 ]; then
        echo Reached the top of the tree
        exit 1
    fi
done

echo $pid

Test:

$ /tmp/find-parent 31177 xterm
31097
share|improve this answer
    
Rather than stop on a command name, stop when you reach a process with a different controlling terminal (tty column in ps). That process is the terminal emulator. –  Gilles Oct 16 '10 at 23:35
1  
nice command line screencast - that gives me the right xterm PID, to actually find it on your screen a second step is needed, like Gilles pointed out –  maxschlepzig Oct 17 '10 at 14:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.