SSH into server, start screen session, change directory

gnu-screen

I want to SSH into a server, start a screen session, cd into path/to/my/script/, and run test.sh there.

As a starter, I tried

ssh me@myserver.com screen -dm bash -c 'cd  path/to/my/script/; pwd > ~/output.txt'

and expected to see path/to/my/script/ in output.txt, but I see my home directory there. This means the cd command doesn't really work, so bash won't be able to run test.sh.

How may I solve this?

Best Answer

The short answer: add some extra quotes around the command, like this:

ssh me@myserver.com "screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'" 

To see what's going on, you can specify the -v option to ssh to obtain some debug information. In this case, you'll see a line like the following for the original command

debug1: Sending command: screen -dm bash -c cd path/to/my/script/; pwd > ~/output.txt

while the extra quotes change this into

debug1: Sending command: screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'

So it appears that ssh just takes the arguments that were passed to it, concatenates them all, and lets the remote side split the concatenated argument list again into individual arguments. Calling the argument list argv (like in C), you've got something like the following in the original version:

argv[0] = ssh
argv[1] = me@myserver.com
argv[2] = screen
argv[3] = -dm
argv[4] = bash
argv[5] = -c
argv[6] = cd path/to/my/script/; pwd > ~/output.txt

Now in principle, it would have been possible for ssh to pass argv[2] to argv[6] as separate arguments to the other side, in which case it would probably have worked as expected. But as the debug line shows (and it also seems like this based on the source code), these arguments are concatenated to the string

screen -dm bash -c cd path/to/my/script/; pwd > ~/output.txt

which is then interpreted at the remote end. From this it's also clear why it doesn't do what you'd like: now you're executing two things in sequence, first screen -dm bash -c cd path/to/my/script/ (so a screen session is started in which only the directory is changed) is executed from the home directory, and then pwd > ~/output.txt is executed, also from the home directory.

For completeness, the arguments for the command with the double quotes are

argv[0] = ssh
argv[1] = me@myserver.com
argv[2] = screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'

causing screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt' to be sent to the other side (as shown by the debug line), which does work as intended.

Related Question