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 [email protected]
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 [email protected] 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 [email protected] 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?
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):(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.This does what you wanted
bash -l -c screen -R
to do: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 seebash -l -c screen -R
.This would do it too, with the remote shell being given the command string
bash -l -c screen\ -R
:Or this, to give the remote shell
bash -l -c "screen -R"
: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.