66

I want to be able to launch screen sessions on remote servers from a single ssh command on my desktop. However, screen seems to need a terminal, which is not available when running a command through ssh.

So the obvious

ssh [email protected] screen "tail -f /var/log/messages"

(as an example) does not work, and gives

Must be connected to a terminal.

I want ssh to launch the command under a screen so I can log in later and attach as I would to a screen session I would have launched manually.

1
  • As an aside, you can hit this error not through bad usage of screen. I had a shell function that was doing exec < foo to read from a file. Much later in a large script I tried to launch screen. All the methods below obv. failed as the real culprit was the exec. One to bear in mind. Check you've not killed your own stdin inadvertently.
    – Goblinhack
    Feb 25, 2015 at 21:12

5 Answers 5

89

Try using the -t option to ssh

ssh -t [email protected] screen "tail -f /var/log/messages"

From man ssh

-t      Force pseudo-tty allocation.  This can be used to execute arbi-
        trary screen-based programs on a remote machine, which can be
        very useful, e.g., when implementing menu services.  Multiple -t
        options force tty allocation, even if ssh has no local tty.
3
  • I am trying the same with tmux ssh -t user@machine tmux attach and I can attach a remote tmux session but it messes with the character encoding. It displays only ascii chars. Is there a fix for this?
    – Macario
    Jul 31, 2012 at 8:22
  • 1
    @Macario you may want to open a separate question for this, while it's tangentially related as you're running it with ssh -t, it sounds more like it's related to setting LC_* differently for running interactively vs. non-interactively. When you pass a command-line to ssh to execute, it'll be executed with the non-interactive environment. It's also possible it's the lack of the TERM environment variable being passed when executing non-interactively, in which case tmux would have no idea what capabilities your terminal actually has, and falls back to the least common denominator. Aug 1, 2012 at 0:34
  • I am not using ssh but is facing the same issue. Please help. serverfault.com/questions/861632/unable-to-run-code-in-screen Jul 11, 2017 at 21:23
39

You can use:

ssh root@host screen -m -d "tail -f /var/log/messages"

That starts a detached screen with a command running on it.

   -m   causes screen  to  ignore  the  $STY  environment  variable.  With
        "screen  -m"  creation  of  a  new session is enforced, regardless
        whether screen is called from within  another  screen  session  or
        not.  This  flag has a special meaning in connection with the `-d'
        option:

   -d -m   Start screen in "detached" mode. This creates a new session but
           doesn't  attach  to  it.  This  is  useful  for  system startup
           scripts.
4
  • 1
    Your answer was equally good, too bad I have to choose. Maybe someone should edit the first answer and add your information. Jun 9, 2009 at 13:57
  • 1
    This answer is better because it does detach and thus lets you continue working in this terminal (and to attach to the screen session from anywhere else).
    – Ruslan
    Aug 6, 2020 at 19:07
  • Hwo can we choose a name for that screen as well?
    – Diamond
    Jun 25, 2021 at 18:48
  • I am already ssh'ed to a remote server. From that shell, I want to shh to another server, When I run this command, it seems that it connects to the server (no error is printed), although after that, when I run "screen -ls", I get "No Sockets found in /var/run/screen/S-myname".
    – Diamond
    Jun 25, 2021 at 18:57
8

Late answer, but this is what I do, I make an alias (let's call it t) that does this:

ssh $MYSERVER -a -x -t screen -xRR -A -e^Zz -U -O

This tells ssh to disable agent and X11 forwarding, and tells screen to attach to a running session, start a new one if needed, use ^Z as the breakout command, use UTF-8 and be smart about the terminal.

All this means that I can open a terminal, type t and it will open my screen session on $MYSERVER. I can then open another terminal, do the same thing and I get another window to the same session.

It's really nice to have multiple terminal windows to the same screen session so you get to look at two screens tabs at the same time.

2
  • 1
    I read through quite a few pages not quite answering what I was looking for but you nailed it. I'm assuming either screen or tmux is probably on most servers these days, and the ones I connect to are potentially ephemeral so I didn't want to mess with the bashrc like most answers suggest. You can also make this a function in your shell and accept arguments like $host and $command (which you would put at the end). And rather than hardcoding your alias to t which is a single host, you could combine it with hostnames in your ssh_config.
    – dragon788
    Jun 16, 2017 at 23:40
  • @dragon788 indeed, I made it a function now and replaced $MYSERVER with "$@". I still use this one a lot.
    – w00t
    Jun 17, 2017 at 5:19
4

By putting the following in the ~/.bashrc file on my server, it starts a screen session the first time I log on to the server, or if one is already running, re-connects me to that session.

I find this very handy:

if [ -n "$SSH_CONNECTION" ] && [ -z "$SCREEN_EXIST" ]; then
    export SCREEN_EXIST=1
    screen -DRi
fi
1
  • I tried this, but when I do screen -ls then I don't see any screen session
    – Tarun
    Oct 23, 2015 at 10:29
0

the accepted answer works for executing a simple command but not for executing somewhat more complex commands (for example multiple commands using the "&&" operator). In that case it may be needed to invoke the command using "sudo" and a shell invocation, e.g.:

ssh -t [email protected] sudo -- "screen bash -c 'test -e /var/log/messages && tail -f /var/log/messages'"

or only using a shell invocation:

ssh -t [email protected] 'screen bash -c "test -e /var/log/messages && tail -f /var/log/messages"'

you may also consider adding an "exec bash" at the end to keep the session open afterwards, e.g.:

ssh -t [email protected] 'screen bash -c "test -e /var/log/messages && tail /var/log/messages ; exec bash"'

if you just want to create the remote screen session and immediately detach from it afterwards you may also consider using the screen options "-d -m", e.g.:

ssh -t [email protected] sudo -- "screen -S test123 -d -m bash -c 'test -e /var/log/messages && tail -f /var/log/messages'"

you can later on reattach to the remote screen session using:

ssh -t [email protected] 'screen bash -c "screen -x test123 ; exec bash"'

The screen option "-S test123" is used to name the session and option "-x test123" to reattach to the session.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .