Run Remote ssh command with Full Login Shell

49

7

I would like to do something like ssh example.com 'ls' However per ssh manpage:

If command is specified, it is executed on the remote host instead of a login shell.

So what happens is that ls displays it's output and then ssh exits.

What I can't figure out is how to have the full login shell open and then have the command run inside that shell. Leaving the shell open after the command is run. As if I had manually done the following:

  localhost$ ssh example.com 
example.com$ ls
             /folder1 
             /folder2 
example.com$ _

Any ideas?

matthew

Posted 2011-07-05T14:14:28.737

Reputation: 737

this is a similar question http://superuser.com/questions/261617/with-ssh-how-can-you-run-a-command-on-the-remote-machine-without-exiting but none of the answers really seem to fit what I'm trying to do.

– matthew – 2011-07-05T14:16:59.513

How about ssh example.com 'ls;bash'? – Andrejs Cainikovs – 2011-07-05T14:40:34.153

you need the -i on my systems to make the second shell an interactive one. – Flexo – 2011-07-05T15:01:50.203

option -t is the answer to your question. Other options (for example keychain) exist but depends on your real needs, which are not clear enough to me . – hornetbzz – 2011-07-05T23:33:58.813

@hornetbzz -t gives me pseudo-tty. But otherwise the behavior is the same. I want to launch an interactive shell, run a command inside that shell and have the shell remain open after the command is run. – matthew – 2011-07-06T03:50:20.137

Answers

40

Just tell bash to execute ls and then itself in a login shell

$ ssh user@host  -t 'bash -l -c "ls;bash"'

fons

Posted 2011-07-05T14:14:28.737

Reputation: 486

2Unfortunately this doesn't appear to work while using screen. Otherwise this seems like it does what I was trying to do. – matthew – 2013-07-17T17:57:56.213

32

ssh user@host -t 'ls; exec $SHELL -l'

-t Force pseudo-terminal allocation. This can be used to execute arbitrary screen-based programs on a remote machine. Is slightly more proper than bash -i.

exec No new process is created.

-l looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from ... Without this you probably can not run scripts/commands from ~/bin directory, because this code from ~/.profile will not be executed without -l flag:

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

user1686

Posted 2011-07-05T14:14:28.737

Reputation: 283 655

@matthew, use exec bash or exec $SHELL – Eugen Konkov – 2016-03-01T08:44:35.437

@grawity @Alan This might work as a workaround, but I'd really like the command to run inside the shell and not just open a new shell after the command is run. – matthew – 2011-07-05T15:46:36.130

+1, -t is definitely the right way to go over -i, I just forgot about it. – Flexo – 2011-07-05T15:50:13.563

@matthew: You'll have to patch bash yourself to allow that. – user1686 – 2011-07-06T14:34:56.377

@grawity not really, see my answer below – fons – 2013-07-17T15:59:15.113

1

In your comment on fons's answer, you say that it doesn't work while using screen.

Could you elaborate on that? Looking at the source code for openssh, sshd executes the command by calling

YOUR_DEFAULT_SHELL -c COMMAND

So, for example, if your default shell is screen, then this won't work all that well because screen's -c flag just overrides its .scrreenrc. So, there's really no way to send commands to screen if it's your default shell. You'll have to actually run screen as the command given to ssh, but with a default shell that isn't screen.

If that's what you're trying to do, I think things will get really weird, since screen will also close windows with non-interactive programs, so you'll have to do a similar trick to fons's, but one level deeper. SO, with, e.g. /bin/bash (and not screen) as your default shell Something like:

ssh user@host -t 'screen bash -l -c "ls;bash"'

Which should --take a deep breath-- ssh into the host, run bash -c with a command of screen, which will make a new window. If this window just opened up ls, it would end, and screen would terminate, so we use fons's trick inside the new screen window.

I think that'll work, if that's even what you were trying to do ;)

Scott Walls

Posted 2011-07-05T14:14:28.737

Reputation: 66

I think the problem I have with screen in this situation, is that I normally load it with exec screen -RR from my .profile. This means that bash -l tries to load screen which throws off the rest of it. it seems I can get around it by removing '-l' in both yours and @fons solutions (yours then leaves me in screen). It's kind of wonky though. – matthew – 2013-07-24T15:33:56.137

0

Multiple -t options force tty allocation, even if ssh has no local tty:

ssh -tt user@host 'bash -l -c "/path/to/command'

panticz.de

Posted 2011-07-05T14:14:28.737

Reputation: 231