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.

Amelio Vazquez-Reina
  • 40,169
  • 77
  • 197
  • 294
  • I don't think you can. But I'm puzzled as to why you want this. There's already a command on the ssh command line. Why can't you run `ssh mycommand`? And if you want to run some setup command before every command that comes over ssh, why not configure the server side? – Gilles 'SO- stop being evil' Sep 14 '11 at 23:22
  • Thanks @Guilles. I'm in a situation where multiple users are sharing the same remote account, so I would like to quickly set up a few things as I log in remotely. More specifically, I'd like to start a Z shell and ask it to run a `.zshrc` in a specific directory (i.e. a "personal" home directory). I tried `ssh -t host_name 'zsh & source /path/to/my_zshrc'` but it didn't work (I got `FPATH variable not defined`, and I think it is because `zsh` finishes before it runs `my_zshrc`, let alone this didn't give me a Z shell) – Amelio Vazquez-Reina Sep 14 '11 at 23:28
  • I think this deserves an update of the OP, so I just updated it. – Amelio Vazquez-Reina Sep 14 '11 at 23:39
  • Having gone looking for a similar answer of mine, it occurs to me that [this question](http://unix.stackexchange.com/questions/14919/is-there-a-way-to-push-shell-config-information-when-sshing-to-a-host) is pretty close to what you're trying to do. – Gilles 'SO- stop being evil' Sep 14 '11 at 23:43
  • I posted a related question: [ssh, start a specific shell (ash), and source your environment on the remote machine](https://unix.stackexchange.com/q/677145/114401) – Gabriel Staples Nov 11 '21 at 23:33

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 [email protected] '. ~/.profile; command_that_needs_environment_variables'
ssh -t [email protected] '. ~/.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 [email protected] '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…== [email protected]
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • 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 [email protected] '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](http://unix.stackexchange.com/questions/234393/passing-variable-definitions-to-specific-shells-in-zsh). – 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](https://meta.stackexchange.com/questions/66377/what-is-the-xy-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](https://unix.stackexchange.com/q/677145/114401). 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