Running shell commands on a remote machine
If you’re familiar with unix-like systems, probably you’ve already worked with shell commands. My favorite shell is Bash and this post is about running Bash commands on a remote machine; but I guess the idea behind it can be used in other Unix shell systems too.
As a web developer, I frequently have to deploy projects to remote servers. When something changes, I need to re-deploy the whole project (especially when I work on projects written in Java). The easiest way for me is to write a deployment script that automatically goes over the boring mandatory steps (e.g. backing up the latest version on the remote server, copying files, preparing the package). This way is even more secure. Once I’m sure that the script does its job correctly, it does not have a choice to make a mistake.
During my first attempt to write such a script, I faced a problem when I wanted some commands of the script to work on the remote machine. Normally, to work on a remote machine you make a connection via ssh, find yourself on its shell and continue writing your commands. Here, the problem is that the script works on your local machine and if you open an ssh connection, it just gets stuck. A workaround for this problem is running commands like this:
ssh -p PORT_NUMBER USERNAME:PASSWORD@REMOTE_MACHINE_IP "cd /var/www; ls;"
The trick here is to append the desired commands after the connection command. But if the job you’re doing is complicated enough, appending such commands may drive you to have problems.
My solution to this problem is to write a second bash script, copying it to the remote server via scp and running that script remotely. Yes, of course it works and is a great idea! Let’s assume that the name of the bash script file is ss-script.sh (ss stands for Server-Side). In our local deployment script, let’s add these lines:
scp -P POST_NUMBER ss-script.sh USERNAME:PASSWORD@REMOTE_MACHINE_IP:/tmp
ssh -p PORT_NUMBER USERNAME:PASSWORD@REMOTE_MACHINE_IP "cd /tmp; chmod 777 ss-script.sh; ./ss-script.sh"
And that’s it! The script would work as expected and after it’s finished, your local script will continue to work from the next line!