如何使用SSH在远程计算机上运行本地shell脚本?

如何使用SSH在远程计算机上运行本地shell脚本?,shell,ssh,sysadmin,remote-execution,Shell,Ssh,Sysadmin,Remote Execution,我必须在远程机器上运行本地shell脚本(windows/Linux) 我在机器A和B上都配置了SSH。我的脚本在机器A上,它将在远程机器B上运行我的一些代码 本地和远程计算机可以是基于Windows或Unix的系统 有没有办法使用plink/ssh运行并执行此操作?$sshuser@hostB“ls-la” <hostA_shell_prompt>$ ssh user@hostB "ls -la" 这将提示您输入密码,除非您已将hostA用户的公钥复制到user.ssh目录的h

我必须在远程机器上运行本地shell脚本(windows/Linux)

我在机器A和B上都配置了SSH。我的脚本在机器A上,它将在远程机器B上运行我的一些代码

本地和远程计算机可以是基于Windows或Unix的系统

有没有办法使用plink/ssh运行并执行此操作?

$sshuser@hostB“ls-la”
<hostA_shell_prompt>$ ssh user@hostB "ls -la"

这将提示您输入密码,除非您已将hostA用户的公钥复制到user.ssh目录的home上的authorized_keys文件中。这将允许无密码身份验证(如果在ssh服务器的配置上被接受为身份验证方法)

首先,使用scp将脚本复制到机器B上

[user@machineA]$scp/path/to/scriptuser@machineB:/home/user/path

然后,运行脚本

[user@machineA]$sshuser@machineB“/home/user/path/script”


如果您已经为脚本授予了可执行权限,这将起作用。

假设您的意思是希望从“本地”计算机自动执行此操作,而无需手动登录到“远程”计算机,您应该查看称为Expect的TCL扩展,它正是为这种情况而设计的。我还提供了一个链接,指向通过SSH登录/交互的脚本


此外,如果要从目标主机获取变量,请不要忘记转义变量

这让我在过去陷入困境

例如:

user@host> ssh user2@host2 "echo \$HOME"
user@host> ssh user2@host2 "echo hello world | awk '{print \$1}'"
打印输出/home/user2

打印输出/主页/用户

另一个例子:

user@host> ssh user2@host2 "echo \$HOME"
user@host> ssh user2@host2 "echo hello world | awk '{print \$1}'"

正确打印“hello”。

尝试运行
sshuser@remotesh./script.unx

如果机器A是Windows box,您可以使用带有-m参数的Plink(部分),它将在远程服务器上执行本地脚本

plink root@MachineB -m local_script.sh
如果机器A是基于Unix的系统,则可以使用:

ssh root@MachineB 'bash -s' < local_script.sh
sshroot@MachineB“bash-s”

您不必将脚本复制到远程服务器来运行它。

这是一个老问题,Jason的答案很好,但我想补充一下:

ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH
实际上,您可以与一些服务(如telnet、ftp等)进行对话。但请记住,Herdeoc只是以文本的形式发送stdin,它不会在两行之间等待响应


编辑:我刚刚发现,如果您使用我开始用于更复杂操作的
,您可以使用选项卡缩进内部。Fabric需要Python和几个其他依赖项,但仅在客户端计算机上。服务器只需要是ssh服务器。我发现这个工具比交给SSH的shell脚本功能强大得多,并且非常值得费心设置(特别是如果您喜欢用Python编程的话)。Fabric处理在多个主机(或具有特定角色的主机)上运行脚本,有助于促进幂等操作(例如,向配置脚本添加一行,但如果它已经存在,则不会),并允许构造更复杂的逻辑(例如Python语言可以提供的).

这是对YarekT答案的扩展,将内联远程命令与从本地计算机向远程主机传递环境变量相结合,以便您可以在远程端参数化脚本:

ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
  # commands to run on remote host
  echo $ARG1 $ARG2
ENDSSH
sshuser@hostARG1=$ARG1 ARG2=$ARG2'bash-s'如果
您正在尝试使用
plink
ssh
在远程linux机器上运行脚本。 如果脚本在
linux
上有多行代码,它将起作用

**但是,如果您试图运行位于本地服务器上的批处理脚本
linux/windows
机器,您的远程机器是
windows
,它由 使用**

plinkroot@MachineB-m local_script.bat

行不通

只执行脚本的第一行。这可能是一个错误
plink的限制

解决方案1: 要运行多行批处理脚本(特别是在相对简单的情况下), 由几行组成):

如果原始批处理脚本如下所示

cd C:\Users\ipython_user\Desktop 
python filename.py
您可以使用“&&”分隔符将这些行组合在一起,如下所示:
local_script.bat
文件: :

在进行此更改之后,您可以运行脚本,正如 @JasonR.Coombs:与:

解决方案2: 如果批处理脚本相对复杂,则最好使用批处理脚本 封装plink命令的脚本,如下所示 这里是@Martin:


此bash脚本将ssh发送到目标远程计算机,并在远程计算机上运行一些命令,在运行它之前不要忘记安装expect(在mac上
brew安装expect


如果你想执行这样的命令

temp=`ls-a`
echo$temp
“`中的命令将导致错误

下面的命令将解决此问题

sshuser@host '''
temp=`ls-a`
echo$temp
'''

我使用此脚本在远程计算机上运行shell脚本(在/bin/bash上测试):

cat./script.sh | ssh@
强烈建议您作为环境文件(.bashrc/.bashprofile/.profile)的源文件。在远程主机中运行某项操作之前,因为目标主机和源主机环境变量可能会被定义。

您可以使用:

sudo-apt-install runoversh
runoverssh-s localscript.sh用户host1 host2 host3。。。
-s
远程运行本地脚本


有用标志:
-g
为所有主机使用全局密码(单一密码提示)

-n
使用SSH而不是sshpass,这对公钥身份验证非常有用

如果是一个脚本,则可以使用上述解决方案

我会设置Ansible来做这项工作。它以同样的方式工作(Ansible使用ssh在Unix或Windows的远程机器上执行脚本)

它将更加结构化和可维护。

chmod
chmod +x script.sh    
ssh -i key-file root@111.222.3.444 < ./script.sh
cd C:\Users\ipython_user\Desktop && python filename.py
`plink root@MachineB -m local_script.bat`
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
#!/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"
ssh deploy@host . /home/deploy/path/to/script.sh
cat ./script.sh | ssh <user>@<host>
ssh user@hostname ".~/.bashrc;/cd path-to-file/;.filename.sh"
chmod +x script.sh    
ssh -i key-file root@111.222.3.444 < ./script.sh
#!/bin/bash

myalias $myvar
myfunction $myvar
eval "myfun() { `cat myscript.sh`; }"
myvar=works
alias myalias='echo This alias'
myfunction() { echo This function "$@"; }
env_parallel -S server -N0  --nonall myfun ::: dummy
somevar="spaces or other special characters"
somevar2="!@#$%^"
another_func() {
    mkdir -p "$1"
}
work() {
    another_func "$somevar"
    touch "$somevar"/"$somevar2"
}
ssh user@server 'bash -s' <<EOT
$(declare -p somevar somevar2)    # transfer variables values
$(declare -f work another_func)   # transfer function definitions
work                              # call the function
EOT