shell - without - ssh run local script remotely with arguments




How to use SSH to run a shell script on a remote machine? (8)

Also, don't forget to escape variables if you want to pick them up from the destination host.

This has caught me out in the past.

For example:

[email protected]> ssh [email protected] "echo \$HOME"

prints out /home/user2

while

[email protected]> ssh [email protected] "echo $HOME"

prints out /home/user

Another example:

[email protected]> ssh [email protected] "echo hello world | awk '{print \$1}'"

prints out "hello" correctly.

I have to run a shell script (windows/Linux) on a remote machine.

I have SSH configured on both machine A and B. My script is on machine A which will run some of my code on a remote machine, machine B.

The local and remote computers can be either Windows or Unix based system.

Is there a way to run do this using plink/ssh?


Assuming you mean you want to do this automatically from a "local" machine, without manually logging into the "remote" machine, you should look into a TCL extension known as Expect, it is designed precisely for this sort of situation. It's home page below looks kind of crappy but don't let that dissuade you; I've also provided a link to a script for logging-in/interacting via SSH.

http://expect.nist.gov/

http://bash.cyberciti.biz/security/expect-ssh-login-script/


I've started using Fabric for more sophisticated operations. Fabric requires Python and a couple of other dependencies, but only on the client machine. The server need only be a ssh server. I find this tool to be much more powerful than shell scripts handed off to SSH, and well worth the trouble of getting set up (particularly if you enjoy programming in Python). Fabric handles running scripts on multiple hosts (or hosts of certain roles), helps facilitate idempotent operations (such as adding a line to a config script, but not if it's already there), and allows construction of more complex logic (such as the Python language can provide).


If Machine A is a Windows box, you can use Plink (part of PuTTY) with the -m parameter, and it will execute the local script on the remote server.

plink [email protected] -m local_script.sh

If Machine A is a Unix-based system, you can use:

ssh [email protected] 'bash -s' < local_script.sh

You shouldn't have to copy the script to the remote server to run it.


This bash script does ssh into a target remote machine, and run some command in the remote machine, do not forget to install expect before running it (on mac brew install expect )

#!/usr/bin/expect
set username "enterusenamehere"
set password "enterpasswordhere"
set hosts "enteripaddressofhosthere"
spawn ssh  [email protected]$hosts
expect "[email protected]$hosts's password:"
send -- "$password\n"
expect "$"
send -- "somecommand on target remote machine here\n"
sleep 5
expect "$"
send -- "exit\n"

This is an extension to YarekT's answer to combine inline remote commands with passing ENV variables from the local machine to the remote host so you can parameterize your scripts on the remote side:

ssh [email protected] ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
  # commands to run on remote host
  echo $ARG1 $ARG2
ENDSSH

I found this exceptionally helpful by keeping it all in one script so it's very readable and maintainable.

Why this works. ssh supports the following syntax:

ssh [email protected] remote_command

In bash we can specify environment variables to define prior to running a command on a single line like so:

ENV_VAR_1='value1' ENV_VAR_2='value2' bash -c 'echo $ENV_VAR_1 $ENV_VAR_2'

That makes it easy to define variables prior to running a command. In this case echo is our command we're running. Everything before echo defines environment variables.

So we combine those two features and YarekT's answer to get:

ssh [email protected] ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'...

In this case we are setting ARG1 and ARG2 to local values. Sending everything after [email protected] as the remote_command. When the remote machine executes the command ARG1 and ARG2 are set the local values, thanks to local command line evaluation, which defines environment variables on the remote server, then executes the bash -s command using those variables. Voila.



if you wanna execute command like this temp=`ls -a` echo $temp command in `` will cause errors.

below command will solve this problem ssh [email protected] ''' temp=`ls -a` echo $temp '''





remote-execution