如何使用SSH在远程计算机上运行本地shell脚本?
我必须在远程机器上运行本地shell脚本(windows/Linux) 我在机器A和B上都配置了SSH。我的脚本在机器A上,它将在远程机器B上运行我的一些代码 本地和远程计算机可以是基于Windows或Unix的系统 有没有办法使用plink/ssh运行并执行此操作?如何使用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
$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