3

I have a linux box in the office I want to ssh into from my Macbook at home. I can’t reach the box directly on port 22, but I have a port tunnel nailed up between localhost:23001 and port 22 on the remote linux box. This works for a regular ssh session:

$ ssh -t -2 -A -p 23001 roysmith@127.0.0.1

The next step is, I want to automatically run my terminal session inside a screen session. It almost works to do:

$ ssh -t -2 -A -p 23001 roysmith@127.0.0.1  screen -R

If I don’t have a current screen session, it creates one. If there’s already a detached screen, it connects to it. So far, so good. But, the problem is, I never get a login shell, so my .profile never gets run and my environment doesn’t get set up. So, I went one step further, and tried:

$ ssh -t -2 -A -p 23001 roysmith@127.0.0.1  bash -l -c screen -R

Now, I get a real login shell which runs .profile, but screen fails to re-attach to a detached session. I run the above command on my Macbook, and on the remote machine, I’ve got an attached screen:

$ screen -list
There is a screen on:
    21117.pts-21.roysmith01 (01/19/2015 01:50:59 PM)    (Attached)
1 Socket in /var/run/screen/S-roysmith.

If I close the window where I ran the above ssh line, the session gets detached, as expected:

$ screen -list
There is a screen on:
    21117.pts-21.roysmith01 (01/19/2015 01:50:59 PM)    (Detached)
1 Socket in /var/run/screen/S-roysmith.

Now, if I open another local terminal window and run that ssh command again, screen fails to find the detached session and creates a new one:

$ screen -list
There are screens on:
    21304.pts-21.roysmith01 (01/19/2015 01:52:40 PM)    (Attached)
    21117.pts-21.roysmith01 (01/19/2015 01:50:59 PM)    (Detached)
2 Sockets in /var/run/screen/S-roysmith.

Any idea what’s going on here? Why does inserting a login shell keep screen from locating existing sessions?

Roy Smith
  • 483
  • 1
  • 4
  • 6
  • Have you checked the permissions on the sockets in /var/run/screen? What happens if you use 'screen -D -RR' instead? – Phil Hollenback Jan 19 '15 at 22:47
  • -D -RR still doesn't attach to an existing session; it generates a new one. I just generated three sessions, one with "screen -R", one with "bash -l -c screen -R", and one with "bash -l -C screen -D -RR". They all generate the same permissions: ``` $ ls -l /var/run/screen/S-roysmith/ total 0 prwx------ 1 roysmith eng 0 Jan 19 18:02 32644.pts-20.roysmith01 prwx------ 1 roysmith eng 0 Jan 19 18:03 468.pts-28.roysmith01 prwx------ 1 roysmith eng 0 Jan 19 18:06 760.pts-22.roysmith01 ``` – Roy Smith Jan 19 '15 at 23:04

2 Answers2

1

If there is no existing session to connect to, screen will use whatever command you give after the -R flag. So this should do what you want (without having to touch .screenrc):

$ ssh [...]@127.0.0.1 screen -R bash -l

(This is surely the simplest way to do what you originally set out to do.)

But since you asked, I'll also mention why your bash -l approach didn't work. It was so close!

bash -c takes only the very next argument as a command. Arguments after that go into $0, $1, etc.

$ bash -c echo bar
[just a blank line]
$ bash -c 'echo foo'
foo
$ bash -c 'echo $1' foo bar baz
bar

This does what you wanted bash -l -c screen -R to do:

$ ssh [...]@127.0.0.1 bash -l -c "'screen -R'"

Yes, excitingly you do need two levels of quoting for that to work: the outer quotes tell your local shell to preserve the inner quotes, and the inner quotes are needed because ssh sends the resulting command, bash -l -c 'screen -R', as a string with four spaces in it, not as a list of four words. With one level of quotes, the remote shell would still see bash -l -c screen -R.

This would do it too, with the remote shell being given the command string bash -l -c screen\ -R:

$ ssh [...]@127.0.0.1 bash -l -c 'screen\ -R'

Or this, to give the remote shell bash -l -c "screen -R":

$ ssh [...]@127.0.0.1 bash -l -c \"screen -R\"
tomclegg
  • 301
  • 1
  • 2
0

I found How do I ask screen to behave like a standard bash shell?, which pointed me in the right direction. Putting "defshell -bash" in my .screenrc gets me the behavior I want. With I could figure out what screen is really doing, however. I hate finding things that work without understanding why.

Roy Smith
  • 483
  • 1
  • 4
  • 6