问题
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?
回答1:
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 root@MachineB -m local_script.sh
If Machine A is a Unix-based system, you can use:
ssh root@MachineB 'bash -s' < local_script.sh
You shouldn't have to copy the script to the remote server to run it.
回答2:
This is an old question, and Jason's answer works fine, but I would like to add this:
ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH
This can also be used with su and commands which require user input. (note the '
escaped heredoc)
Edit: Since this answer keeps getting bits of traffic, i would add even more info to this wonderful use of heredoc:
You can nest commands with this syntax, and thats the only way nesting seems to work (in a sane way)
ssh user@host <<'ENDSSH'
#commands to run on remote host
ssh user@host2 <<'END2'
# Another bunch of commands on another host
wall <<'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.secureftp-test.com <<'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH
You can actually have a conversation with some services like telnet, ftp, etc. But remember that heredoc just sends the stdin as text, it doesn't wait for response between lines
Edit: I just found out that you can indent the insides with tabs if you use <<-END
!
ssh user@host <<-'ENDSSH'
#commands to run on remote host
ssh user@host2 <<-'END2'
# Another bunch of commands on another host
wall <<-'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.secureftp-test.com <<-'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH
(I think this should work)
Also see http://tldp.org/LDP/abs/html/here-docs.html
回答3:
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:
user@host> ssh user2@host2 "echo \$HOME"
prints out /home/user2
while
user@host> ssh user2@host2 "echo $HOME"
prints out /home/user
Another example:
user@host> ssh user2@host2 "echo hello world | awk '{print \$1}'"
prints out "hello" correctly.
回答4:
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 user@host 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 user@host 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 user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'...
In this case we are setting ARG1 and ARG2 to local values. Sending everything after user@host 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.
回答5:
<hostA_shell_prompt>$ ssh user@hostB "ls -la"
That will prompt you for password, unless you have copied your hostA user's public key to the authorized_keys file on the home of user .ssh's directory. That will allow for passwordless authentication (if accepted as an auth method on the ssh server's configuration)
回答6:
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).
回答7:
Try running ssh user@remote sh ./script.unx
.
回答8:
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. I've also provided a link to a script for logging-in/interacting via SSH.
https://www.nist.gov/services-resources/software/expect
http://bash.cyberciti.biz/security/expect-ssh-login-script/
回答9:
I use this one to run a shell script on a remote machine (tested on /bin/bash):
ssh deploy@host . /home/deploy/path/to/script.sh
回答10:
if you wanna execute command like this
temp=`ls -a`
echo $temp
command in `` will cause errors.
below command will solve this problem
ssh user@host '''
temp=`ls -a`
echo $temp
'''
回答11:
The answer here (https://stackoverflow.com/a/2732991/4752883) works great if
you're trying to run a script on a remote linux machine using plink
or ssh
.
It will work if the script has multiple lines on linux
.
**However, if you are trying to run a batch script located on a local
linux/windows
machine and your remote machine is Windows
, and it consists
of multiple lines using **
plink root@MachineB -m local_script.bat
wont work.
Only the first line of the script will be executed. This is probably a
limitation of plink
.
Solution 1:
To run a multiline batch script (especially if it's relatively simple, consisting of a few lines):
If your original batch script is as follows
cd C:\Users\ipython_user\Desktop
python filename.py
you can combine the lines together using the "&&" separator as follows in your
local_script.bat
file:
https://stackoverflow.com/a/8055390/4752883:
cd C:\Users\ipython_user\Desktop && python filename.py
After this change, you can then run the script as pointed out here by @JasonR.Coombs: https://stackoverflow.com/a/2732991/4752883 with:
`plink root@MachineB -m local_script.bat`
Solution 2:
If your batch script is relatively complicated, it may be better to use a batch script which encapsulates the plink command as well as follows as pointed out here by @Martin https://stackoverflow.com/a/32196999/4752883:
rem Open tunnel in the background
start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH
key]" -N
rem Wait a second to let Plink establish the tunnel
timeout /t 1
rem Run the task using the tunnel
"C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R
rem Kill the tunnel
taskkill /im plink.exe
回答12:
ssh user@hostname ".~/.bashrc;/cd path-to-file/;.filename.sh"
highly recommended to source the environment file(.bashrc/.bashprofile/.profile). before running something in remote host because target and source hosts environment variables may be deffer.
回答13:
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 $username@$hosts
expect "$username@$hosts's password:"
send -- "$password\n"
expect "$"
send -- "somecommand on target remote machine here\n"
sleep 5
expect "$"
send -- "exit\n"
回答14:
cat ./script.sh | ssh <user>@<host>
回答15:
You can use runoverssh:
sudo apt install runoverssh
runoverssh -s localscript.sh user host1 host2 host3...
-s
runs a local script remotely
Useful flags:-g
use a global password for all hosts (single password prompt)-n
use SSH instead of sshpass, useful for public-key authentication
回答16:
First, copy the script over to Machine B using scp
[user@machineA]$ scp /path/to/script user@machineB:/home/user/path
Then, just run the script
[user@machineA]$ ssh user@machineB "/home/user/path/script"
This will work if you have given executable permission to the script.
来源:https://stackoverflow.com/questions/305035/how-to-use-ssh-to-run-a-shell-script-on-a-remote-machine