36

Whenever I login to my Linux server I'd like to have several commands run automatically (set some variables, change location, etc.)

This needs to be done on user login, not on system start.

How can I set it to do this?

1
  • You need to read the section INVOCATION in bash(1) (man bash). Nov 8, 2011 at 9:39

7 Answers 7

43

Put the commands in ~/.bashrc. Anything in there is executed each time you log in.

If you need commands to only run when logging in via ssh (but not when logging in physically), you could probably test for the presence of the SSH_CONNECTION environment variable, and only run the commands if you find it exists.

9
  • I'm not logging in as root, it's an AWS server so I have to login as "ec2-user" then change to root using "sudo su -". So should I put the commands in "/home/ec2-user/.bashrc"?
    – Alasdair
    Nov 8, 2011 at 6:45
  • 5
    This assumes ~/.bashrc is sourced from your ~/.bash_profile. ~/.bash_profile will be the script that is invoked for a login shell like ssh. I believe ~/.bashrc will get called if you open up a Gnome Terminal, for example, AFTER having already logged in.
    – dgrant
    Nov 8, 2011 at 6:46
  • You've confused me, let me explain more: This is an Amazon Web Services instance, which is a virtually server, so no one will ever physically log in (I'm not even sure if it physically exists as one machine). I login using PUTTY with the username ec2-user. This drops me in /home/ec2-user directory. I then change to root user by typing "sudo su -", which then drops me into "/root", then I have to type a series of commands, including changing me back to "/home/ec2-user" and setting some variables, aliases, etc. So... how would I get it to do this?
    – Alasdair
    Nov 8, 2011 at 6:52
  • Also, since I am changing user, I expect that in the ec2-user bash profile I should put only "sudo su -", and then the rest of the commands in the root bash file?
    – Alasdair
    Nov 8, 2011 at 6:52
  • NOTE: actually, it's .profile that gets called if it exists, unless .bash_profile, exists, then it is called instead.
    – dgrant
    Nov 8, 2011 at 6:52
26

Just put this in ~/.bashrc or /etc/bash.bashrc if you want this for all users:

if [[ -n $SSH_CONNECTION ]] ; then
    echo "I am logged in remotely"
fi
6
  • and how do I lose the session after closing execution?
    – e-info128
    Oct 27, 2014 at 18:47
  • 1
    @WHK What do you mean by losing the session? Oct 28, 2014 at 16:16
  • @Llamageddon: I think he's wondering the same thing I am. If I wanted to put my entire SSH session into screen, I might use your answer and put screen there instead of the echo. The problem with that is that finishing the screen session will return to the SSH prompt instead of logging out. Just writing out this comment gave me the answer, though: add the logout command after the screen command.
    – zondo
    Jan 4, 2017 at 13:53
  • This however does not work for ssh session which do not use bash, e.g. when I open an sftp session.
    – Fabio
    Jan 28, 2017 at 10:49
  • @zondo @e-info128 exec command will replace the current shell with whatever you run. Jan 29, 2017 at 12:37
16

Alternatively, you can specify a command to be run during the invocation of ssh:

$ ssh -t server 'cmd; exec bash -l'

The last command in the list should start an interactive session in your preferred shell. If you have a lot of commands to run, consider creating a script file on your SSH server.

1
  • 2
    THIS is very useful. Not sure if it's exactly the answer the questioner asked, but people should know about it, since it may not be obvious. For example "ssh user@host "export x=5; bash" Then in terminal that pops up echo $x displays 5.
    – clearlight
    Jul 26, 2019 at 12:00
12

Actually ~/.ssh/rc is a right place for you to add command to run when you log in, rather than any user of the system.

 ~/.ssh/rc
         Commands in this file are executed by ssh when the user logs in,
         just before the user's shell (or command) is started.  See the
         sshd(8) manual page for more information.
3
  • Not necessarily. It is a location where commands can be placed.
    – Daniel B
    Nov 9, 2018 at 6:44
  • That could REALLY get someone into trouble if they didn't know what they are doing. It's potentially useful in corner cases, but that could REALLY mess someone up if they forgot they put commands there or the name and the path of that file. Gennerally it would be highly preferred to put the startup login commands in the expected place, .bashrc on the remote side and test for $SSH_CONNECTION, as other answers here have suggested.
    – clearlight
    Jul 26, 2019 at 12:29
2

If you use a SSH config file to connect, you can embed a startup command that will only execute when you connect the host.

For this insert / edit the following into your ~/.ssh/config on your client machine:

Host myhost
  HostName *.*.*.*
  User root
  RequestTTY force
  RemoteCommand cd / && bash -i

Put the appropriate hostname and append a new line Port XX if the port differs from 22. The sample will cd in the root of the server. && bash -i and RequestTTY force are essential to continue usage of the remote terminal.

To connect to your host you have to install your public key on the target machine that you can retrieve like so:

cat ~/.ssh/id_rsa.pub

And install on the remote like so:

mkdir -p ~/.ssh && chmod 700 ~/.ssh && touch ~/.ssh/authorized_keys && chmod 644 ~/.ssh/authorized_keys && echo "YOUR_PUBLIC_KEY" >> ~/.ssh/authorized_keys

Then you can simply connect the machine like so:

ssh myhost

And it will connect and execute the RemoteCommand.

1
  • To copy keys to the remote server, it's much easier to use ssh-copy-id -i <path_to_your_keyfile>. It will handle all the directory creation and access controls for you. However, the ssh-copy-id command is not available on all systems.
    – JS.
    Aug 4 at 20:27
0

To have a script that will execute for any user on login you can add an additional script in:

/etc/profile.d/

For example:

/etc/profile.d/Hello.sh
Hello `whoami`

On login would produce:

$ ssh MyTestUser@localhost
Hello MyTestUser

The profile script is executed as the user that is logging in. This may or may not be a problem depending on what you want the script to do.

0

Putting script in /etc/profile.d/ is working but for me it made many problems. I put a script (interactive script!) in that folder and when I login from ssh, the script is run with success. But when I reboot the machine, the machine can't boot. my script was interactive means expect to read the user answer for a question. so the boot stuck with no good error. On the second machine (newer PC), the boot stack since the syslog.1 file (/var/log/syslog.1) got to 90GB!!! It looks like the machine gave some answer to the script. the answer was invalid and the script asked for a valid answer and so on and the syslog got bigger and bigger till the machine couldn't boot.

update: I used the idea raised above and it's working. I wanted the script to run only on ssh login and not when the machine boot:

#!/bin/bash

if [[ -n $SSH_CONNECTION ]] ; then # if the string is not null echo "I am logged in remotely using SSH" # the script... else
echo "I am NOT logged in remotely" fi

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.