0

I'm trying to determine whether a command I'm running is within an SSH session. Usually this works fine by checking for $SSH_CONNECTION or walking the process tree and looking for sshd.
However, if I start a screen session locally and then re-attach it through SSH, neither of those works.

Is there some way from within the reattached screen session to determine which shell the session is currently attached to?
The process tree just looks like shell(X) --> screen(Y) --> systemd(1), which makes sense, since the screen session probably gets reparented when I exit the local terminal.

screen -ls does not say anything more than (Attached), with only the PID Y, no helpful PID of where it is currently attached.

The process tree of shell(A) where it is attached includes a single child screen(B), but I cannot find a way to link the PIDs Y and B. I even tried to find the other end of the unix socket being used by screen but it comes up empty. (even checked as root).

Is this just something that isn't possible?

  • ps waux | grep screen might be useful. You could grep against user. Depending on your version/OS, who might be helpful. – somebody Mar 4 at 23:42
  • Is perhaps tty , which will show you the terminal shell running in the screen , or ps T which will show you the currently running processes only within the current shell, something that you are looking for? – BarBar1234 Mar 5 at 5:25
  • Unfortunately neither of those really help. tty printed dev/pts/3 from inside screen, but there's no way to link that to the screen process that initiated the re-attach. ps did list the process with the re-attach command, but that would require argument parsing in a manner that won't really scale. – Soumya Mar 5 at 5:28
  • Sorry, I misread your question and I think what you are looking for is ps -q $(ps h -q $(($$-1)) -o ppid) -o tty,cmd,pid which will give you the tty and pid of the original shell that invoked screen – BarBar1234 Mar 5 at 6:20
  • @BarBar1234 that won't work after re-attach. Of course during the initial screen run I can just walk the process tree. But after I disconnect and re-attach, the parent is systemd(1) and there is no relationship between the screen that re-attached and the screen running the shell. – Soumya Mar 5 at 6:26
0

After a lot of experimentation, here's what I ended up with:

  • Find the screen the shell is running under. Keep walking the pstree until a screen process is found:
    screen_pid=$(pstree -psUA $$ | egrep -o 'screen\([0-9]+\)' | tail -1 | egrep -o '[0-9]+')

  • Look at all opened files for that process. Find the only /dev/pts/* file in that list:
    screen_pts=$(lsof -p $screen_pid | grep /dev/pts | awk '{print $NF}')

  • Find the screen process controlling that psuedo-terminal:
    ps -o pid=,tty= -C screen | grep ${screen_pts/\/dev\/} | awk '{print $1}'

  • From there the parent process will be the shell/ssh/whatever started the screen which is now attached to the shell.

There are definitely some hacky assumptions made here that "work on my machine(tm)", but that's the general idea.

If reliability is required, using stat with st_rdev will eliminate the hacky /dev/pts/5 -> pts/5 replacement. And something similar could be used to filter the list of open files where major(st_rdev) == some value that represents pseudo terminals.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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