13

I am in a situation where several users are sharing the same user account on a remote machine. I have a "personal" directory where I wrote my own .zshrc file, and I would like to have a way to:

  1. Start a ssh session in the remote machine with directives from my ssh config file (e.g. ControlMaster auto)
  2. This session runs a Z shell
  3. It runs a .zshrc in my "personal" directory (not on the shared user's home directory)

It would be nice to have an alias or a simple way of starting such ssh sessions (that's why I thought about using the OpenSSH's config file), but I am open to any other ideas!

Using OpenSSH's config file?

I read on the OpenSSH's ssh_config man page that I can use the directive LocalCommand to specify a command to run locally after successfully connecting to the server. This made me think there may be a way to tell the config file what command to run remotely after connecting to the server, but there doesn't seem to be any.

2 Answers2

15

The most obvious way to run a command remotely is to specify it on the ssh command line. The ssh command is always interpreted by the remote user's shell.

ssh bob@example.com '. ~/.profile; command_that_needs_environment_variables'
ssh -t bob@example.com '. ~/.profile; exec zsh'

Shared accounts are generally a bad idea; if at all possible, get separate accounts for every user. If you're stuck with a shared account, you can make an alias:

ssh -t shared-account@example.com 'HOME=~/bob; . ~/.profile; exec zsh'

If you use public key authentication (again, recommended), you can define per-key commands in ~/.ssh/authorized_keys. See this answer for more explanations. Edit the line for your key in ~/.ssh/authorized_keys on the server (all on one line):

command="HOME=$HOME/bob;
     if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then
       eval \"$SSH_ORIGINAL_COMMAND\";
     else exec \"$SHELL\"; fi" ssh-rsa AAAA…== bob@some.where
  • Fantastic @Guilles. Your contributions to this site are making it a tremendously useful resource for all of us. Thanks so much, really.

    By the way, I didn't know about the exec command. How is exec zsh different from calling zsh directly? Why is it important in this particular case?

    – Amelio Vazquez-Reina Sep 14 '11 at 23:47
  • Hmm, when I run ssh -t shared-account@example.com 'HOME=~/bob; exec zsh' I get HOME=~/bob: command not found. I think I am on tcsh. I get the same problem if I try HOME=/home/bob. I tried on bash and zsh. Any clues what may be causing this? Finally, would the syntax above leave me with the ssh session open? (what I want). Thanks again. – Amelio Vazquez-Reina Sep 15 '11 at 00:04
  • 2
    @intrpc exec replaces the original shell with zsh; without zsh, the original shell would remain in memory until zsh exits and then exit. The main difference is saving a bit of memory, it's not very important. If your login shell is (t)csh, use setenv HOME ~/bob; exec zsh. Finally, since zsh is started with no argument, you get a shell session, like you'd get if you just ran ssh and had zsh as your login shell. – Gilles 'SO- stop being evil' Sep 15 '11 at 00:09
  • Thanks again for your help. One follow up question here. Any way to run more commands, after the exec zsh command? – Amelio Vazquez-Reina Oct 06 '15 at 00:05
  • 1
    @AmelioVazquez-Reina Not conveniently unless you have some control over one of the dot files. You can set the environment variable ZDOTDIR to make zsh look for dot files in a different directory. If you do have some control over the dot files then you can do something like add eval $LC_STARTUP_CODE to $ZDOTDIR/.zshrc and pass the code to execute in the environment variable LC_STARTUP_CODE. – Gilles 'SO- stop being evil' Oct 06 '15 at 10:07
  • Thanks @Gilles. Yes, I do have control over the dot files. I have started a related question here. – Amelio Vazquez-Reina Oct 06 '15 at 23:51
  • how the command is changed if I use identity file which is typical for AWS servers? -t option does not work in that case – Nusrat Nuriyev Sep 17 '17 at 20:14
  • @CEOatApartico Using a key is the normal way to use SSH and doesn't prevent the -t option from working. If something is not working for you, ask a new question and be sure to describe your problem precisely (and not what you assume to be the problem). – Gilles 'SO- stop being evil' Sep 17 '17 at 20:40
  • I have already found the solution , that in case of -i switch the -t option must be specified with following patter 'command; bash -l -c ""' not the -t "" as it is described . But thanks for your help, anyway. – Nusrat Nuriyev Sep 17 '17 at 21:13
  • @CEOatApartico This is not at all related to the use of the -i switch. – Gilles 'SO- stop being evil' Sep 17 '17 at 21:34
  • oh, seems to me , I got it, in case if we need to execute just one command we do not need to start bash shell – Nusrat Nuriyev Sep 17 '17 at 21:42
  • Shouldn't exec zsh come before . ~/.profile so that ~/.profile is sourced in the new shell, not the old one? – Gabriel Staples Nov 11 '21 at 21:42
  • Also, I can't get this to work with the ash shell. It seems to forget all things sourced when I include the ash cmd as part of the ssh command as you have done with the zsh. – Gabriel Staples Nov 11 '21 at 21:42
  • @GabrielStaples On the contrary: exec zsh; . ~/.profile would not read .profile since exec replaces the current shell. If you want zsh to read .zprofile, use exec zsh -l. I don't understand your second comment; how is ash involved? – Gilles 'SO- stop being evil' Nov 11 '21 at 21:46
  • @Gilles'SO-stopbeingevil', please see my follow-up question here: ssh, start a specific shell (ash), and source your environment on the remote machine. My linux device doesn't have bash nor zsh. I'm trying to do this with ash instead. – Gabriel Staples Nov 11 '21 at 22:29
-3

To run a command remotely after connecting the server, add in your .ssh/config file the following snippet

PermitLocalCommand yes

Host <server-ip-address>
    LocalCommand *command*
  • 2
    Thanks @user626129, but as I mentioned in the original question the LocalCommand directive is to run a command on the local shell , not on the remote shell. – Amelio Vazquez-Reina Sep 14 '11 at 22:56