86

When using screen in linux, how can I tell if I'm in a screen or not? I could do exit and I'll exit a screen if I was in one, but if I wasn't, then I'll end up closing my terminal.

When doing screen -r, I could see if I have other screens attached, but how do I know if my current terminal is one of those attached screens?

Jason Plank
  • 2,336
  • 5
  • 31
  • 40
user8125
  • 915
  • 2
  • 7
  • 6
  • Worth noting that, if you're in screen and run `screen -r`, it will inform you that you're in a screen (or, if there are no screens, that lets you know you can't possibly be in one), and if you aren't in a screen, and become attached to one, you can simply type `C-a` (or whatever your screen command key is) + `d` to exit the screen you just entered. So, that's one easy way to tell. Not worth giving as an answer, though, because I'm assuming the OP already knew / dismissed that option. – Parthian Shot Jul 08 '15 at 18:34

9 Answers9

140

Check $STY. If it's null, you're on a "real" terminal. If it contains anything, it's the name of the screen you're in.

If you are not in screen:

eric@dev ~ $ echo $STY
eric@dev ~ $ 

If you are in screen:

eric@dev ~ $ echo $STY
2026.pts-0.ip-10-0-1-71
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
jho
  • 2,243
  • 1
  • 15
  • 10
  • 5
    What does STY stand for? – Steven You Apr 02 '14 at 04:21
  • 2
    @StevenYou All I've ever found is ["alternate socket name"](http://sunsite.ualberta.ca/Documentation/Gnu/screen-3.9.4/html_chapter/screen_22.html). Which doesn't really explain the choice of variable name. – ahruss Jul 28 '14 at 13:49
  • 1
    this works if you are on the same machine which you started the screen. If you ssh to a new machine, you will need to pass the variable. (ie. ssh user@host "STY=$STY") – Aaron Oommen Jun 02 '15 at 13:58
  • 10
    @StevenYou Probably stands for "Screen TYpewriter" or "Socket TYpewriter". [TTY](https://en.wikipedia.org/wiki/Teleprinter) stands for "TeleTYpewriter", [PTY](http://man7.org/linux/man-pages/man7/pty.7.html) stands for "Pseudoterminal TYpewriter". They probably thought it was obvious enough they didn't need to explicitly mention their reasoning. As this conversation proves, they were wrong. – Parthian Shot Jul 07 '15 at 20:51
  • 3
    For what it's worth, this doesn't seem to work with tmux on osx whereas the "$TERM" based check does. – Andrei Bârsan Oct 17 '15 at 23:09
  • 1
    doesn't work if inside `screen` I `su` as another user – sgargel May 14 '19 at 13:33
20

Another way I've done it is to echo $TERM.

 $ echo $TERM
 screen

Since I end up doing this a lot, I added an alias into my .bashrc file:

alias trm='echo $TERM'

This way, whether in screen or not, if I just execute 'trm' it will show me whether I'm in SCREEN or elsewhere (usually XTERM).

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
JJC
  • 9,547
  • 8
  • 48
  • 53
  • To clarify, under Linux the value of $TERM will be `screen.linux` when in a screen session. – Parthian Shot Jul 08 '15 at 17:48
  • happily, the value of $TERM under tmux is "screen" (at least on OS X) – Michael Mar 13 '17 at 21:54
  • 2
    Actually, Parthian, at least in all recent OS-X/macOS, all recent CentOS, and Ubuntu (at least 14.04), $TERM does return just "screen." Not sure what version of OS/Kernel/shell you are seeing "screen.linux" under. – JJC Mar 14 '17 at 10:02
17

Alternative approach to check if you are in screen.

type:

Ctrl-a ?

If you see the screen help you are in screen.

Otherwise you'll get a question mark '?' on the prompt.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
pors
  • 3,856
  • 36
  • 33
  • 3
    This assumes, of course, that `Ctrl` + `a` is the command character for screen. While that will be true for most people, it's worth pointing out that the command character can be overridden by the `-e` flag, so this won't always work. – Parthian Shot Jul 08 '15 at 17:46
  • This works great (Ctrl+a then "escape" for instance). Though I guess it might move your cursor to the beginning fo the current line if you're *not* in a screen... :| – rogerdpack Aug 07 '19 at 16:23
2

Since all of the other methods here rely on environment variables (which can simply be overridden) or the command character for screen (which can also be overridden), the most foolproof way to check would be to list all the ancestors of the current process.

pstree --show-parents -p $$ | head -n 1 | sed 's/\(.*\)+.*/\1/' | grep screen | wc -l

If it prints 1, then the current process you're running has an ancestor with the word 'screen' in the executable's name, otherwise there wasn't.

A more facile visible inspection might be obtained from:

pstree --show-parents -p $$ | head -n 1 | sed 's/\(.*\)+.*/\1/' | less
Parthian Shot
  • 1,390
  • 1
  • 13
  • 24
  • 1
    Interesting approach. However you need neither of `-p`, `head -n 1 | sed 's/\(.*\)+.*/\1/'` and `wc -l` and I would suggest adding -w to grep to be on the safe side (it will only match a program named "screen" and not "screenish"). So this is the final command `pstree --show-parents $$|grep -w screen`. However if someone is messing with your environment variables he could be messing with the executable name as well :) – ndemou Sep 12 '16 at 07:53
2

My solution to the problem is a lot simpler: just hitting TAB makes the full terminal blink (a quick video inversion) if you are inside GNU Screen.

Tested working on most Linux (Ubuntu, Kali, Debian, RaspBerry... etc) and FreeBSD, GUI and any terminal, local or remote, including CtrlAltFn ones.

As an exception for this method, please, note this (rather complex, but possible) case scenario:

  • 1.- SSH into computer A (lets assume Linux).
  • 2.- Enter a new screen -S AScr from remote terminal on computer A.
  • 3.- SSH from GNU Screen AScr terminal into Computer B.
  • 4.- Enter a new screen -S BScr from remote terminal on computer B.

You are inside a Screen on cases 2 and 4, and outside a Screen on cases 1 and 3, but the terminal will blink on cases 2, 3 and 4.

Sopalajo de Arrierez
  • 3,543
  • 4
  • 34
  • 52
1

While ssh'd into a remote (older) system I noticed that $TERM indicated I was using 'screen-256color', however there was no termcap/terminfo entry for that, so I was forced to resort to the following in .bashrc to prevent the terminal from producing occasional garbage:

case $TERM in 
    (screen-256color) export TERM='screen'
esac

to get it to use the plain entry instead.

TL;DR, $TERM will usually indicate if you are in a screen session when ssh'd remotely. You can use case $TERM in (screen*) echo "you are in a screen session"; esac if you just want a visual clue and don't need to do something specific

WebDragon
  • 876
  • 6
  • 12
1

Add one or more of the followings into your .bashrc

  • alias mysession='echo ${STY}'
  • alias myterm='echo ${TERM}'
  • alias isscreen='if test -n "$STY"; then echo " screen session: ${STY}"; else echo " NOT a screen session"; fi'

Then you can know if you are inside a screen by typing simple commands.

wsdzbm
  • 3,096
  • 3
  • 25
  • 28
  • 1
    A variation of this method is to add `${TERM}` to your prompt in `$PS1`. That could also be done in your `.bashrc`. For example, if your `$PS1` is set to something like `[\u@\h \W]\$`, then you could change this with something like `export PS1="[\u@\h ${TERM} \W]\$"` – Rhubbarb Oct 27 '16 at 09:41
  • I now do something like this, except a bit fancier. :). I add a bright "S" in a spot of my prompt when $TERM == 'screen'. Makes it trivial to always know if I'm in it or not, without any typing. I leave the how as an exercise for the reader. – JJC Mar 14 '17 at 10:05
0

The problem with most of the above answers is that we might be in a subshell of an attached screen session. Or we might be opening a shell to a remote host from within a screen session. In the former case, we can walk the process tree parentage and match for the screen program name. In the latter case, most of the time, we can check the TERM variable for something like screen*.

My answer os similar to /u/Parthian-Shot but not so dependent on the pstree utility; the options he use are not available to me. On the other hand, my implementation is still Linux-dependent: for non-Linux systems, one must tweak the ps command; for systems with older shells that don't support arrays, you'll have yet more work-arounds. But anyway:

ps_walk_parents() {
  local tmp
  local ppid=$PPID
  while [[ $ppid != 1 ]]; do
    tmp=($( ps -o ppid,comm -p $ppid ))
    ppid=${tmp[0]}  # grab parent pid
    echo ${tmp[1]}  # output corresponding command name
  done
}
if [[ "$TERM" =~ screen* ]] || ps_walk_parents |grep -qxi screen ; then
  # we are in a screen terminal 
fi

We could optimize our function a bit to stop searching if/when a process parent matches the target command name ("screen"), but in general, the function will only hit 2 to 3 iterations. Presumably you want to put this code in some startup initialization such as .bashrc or .profile or something, so again, not worth optimizing.

Otheus
  • 785
  • 10
  • 18
  • as far as I can tell, your method is useful if we're in a subshell of an attached screen session where the $TERM and $STY are not preserved. Can you give an example of how this will happen because no matter what I tried $TERM and $STY were always preserved. – ndemou Aug 17 '17 at 10:51
  • They are preserved at _startup_, but not necessarily if you drop to a subshell (Try `env -i bash`). Or if your attached terminal is actually attached to a different host via `ssh` and the TERM variable is overwritten in the other hosts' bashrc for instance. – Otheus Aug 18 '17 at 16:22
-3

screen -ls can tell you.

Outside screen:

$ screen -ls
There are screens on:
        16954.pts-1.auds916     (Detached)
        242.pts-8.auds916       (Detached)
2 Sockets in /tmp/screens/S-glennj.

Inside a screen:

$ screen -ls
There are screens on:
        16954.pts-1.auds916     (Attached)
        242.pts-8.auds916       (Detached)
2 Sockets in /tmp/screens/S-glennj.
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 8
    Not really. Just because a screen is Attached doesn't mean that you are inside it. It might just as well be attached/open from another terminal. – andol Apr 06 '12 at 06:11