我在计算机A和B上都配置了SSH。我的脚本在计算机A上,它将在远程计算机上运行一些代码
本地计算机和远程计算机可以是Windows或Unix系统。
是否可以使用plink / ssh来运行此操作?
#1 楼
如果计算机A是Windows机器,则可以将Plink(PuTTY的一部分)与-m参数一起使用,它将在远程服务器上执行本地脚本。plink root@MachineB -m local_script.sh
如果机器A是基于Unix的系统,则可以使用:
ssh root@MachineB 'bash -s' < local_script.sh
您不必将脚本复制到远程服务器上即可运行它。
评论
使用-s选项有什么好处吗?该手册页使我相信,无论是否使用-s,它都会在处理完选项后处理标准输入。
–aeroNotAuto
2011年11月18日,下午5:41
对于需要sudo的脚本,请运行ssh root @ MachineB'echo“ rootpass” | sudo -Sv && bash -s'
–bradley.ayers
2012-09-20 23:32
@ bradley.ayers记得用一个'space'来启动命令以跳过历史记录(P.S.您需要HISTCONTROL = ignoreboth或ignorespace才能使它起作用)
– derenio
2013年6月23日14:38在
@ bradley.ayers在什么情况下,如果您已经以root用户身份登录,则需要sudo?
–布莱恩·施伦克(Brian Schlenker)
2014年1月20日22:41
@Agostino,您可以添加像这样的参数:ssh root @ MachineB ARG1 =“ arg1” ARG2 =“ arg2”'bash -s'
–伊夫·范·布洛霍芬(Yves Van Broekhoven)
2014年7月7日在8:28
#2 楼
这是一个古老的问题,Jason的答案很好用,但我想添加一下:ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH
也可以与su和需要用户输入的命令一起使用。 (请注意
'
逃脱了heredoc)编辑:由于此答案不断带来大量访问量,因此我将为heredoc的这种出色用法添加更多信息:
您可以嵌套使用这种语法的命令,这就是嵌套似乎可以正常工作的唯一方式(明智的方式)
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
您实际上可以与某些服务进行对话,例如telnet,ftp等等,但是请记住,heredoc只是将stdin作为文本发送,它不等待行之间的响应
编辑:我只是发现,如果您使用
<<-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
(我认为这应该起作用)
另请参见
http://tldp.org/LDP/abs/ html / here-docs.html
评论
您可以通过添加以下行来进行临时调整:#$(sleep 5)
–奥利维尔·杜拉克(Olivier Dulac)
13年2月22日在13:45
请注意,如果在终止符(<<'ENDSSH')周围加上单引号,则不会扩展字符串,也不会评估变量。如果要扩展,也可以使用<< ENDSSH或<<“ ENDSSH”。
–麦克
2013年6月18日5:38
当您需要自动化FTP等交互式命令时,可以使用Expect。
– Programaths
14年4月14日在7:35
注意,我有一个伪终端将不会被分配,因为stdin不是终端。信息。必须使用带有-t -t参数的ssh来避免这种情况。在SO上看到这个线程
–布祖特
16-4-1在12:55
如果您尝试使用<<-'END'语法,请确保使用TAB(而不是空格)缩进heredoc结束定界符。请注意,从stackexchange复制/粘贴将为您提供空间。将其更改为选项卡,缩进功能应起作用。
–fbicknel
16年6月24日在17:06
#3 楼
另外,如果要从目标主机中提取变量,请不要忘记对变量进行转义。这使我过去很困惑。
例如:
user@host> ssh user2@host2 "echo $HOME"
打印出/ home / user2
while
user@host> ssh user2@host2 "echo $HOME"
打印出/ home / user
另一个示例:
user@host> ssh user2@host2 "echo hello world | awk '{print $1}'"
正确打印出“ hello”。
评论
但是请注意以下几点:ssh user2 @ host'bash -s'echo $ HOME / home / user2 exit
–errant.info
13年4月30日在6:55
只需添加在ssh会话中运行的for循环中,不得对循环变量进行转义。
– AlexeyDaryin
2014年4月22日在8:00
在许多情况下,修复您的上一个示例的明智方法是ssh user2 @ host2'echo hello world'| awk'{print $ 1}',即在本地运行Awk脚本。如果远程命令产生了大量的输出,那么您当然要避免将其全部复制回本地服务器。顺便说一句,远程命令周围的单引号避免了任何转义的需要。
–tripleee
2015年12月29日在11:34
#4 楼
这是对YarekT答案的扩展,它结合了嵌入式远程命令和将ENV变量从本地计算机传递到远程主机的功能,因此您可以在远程端对脚本进行参数设置:ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
# commands to run on remote host
echo $ARG1 $ARG2
ENDSSH
我发现将它们全部保存在一个脚本中非常有帮助,因此它非常易读和可维护。
为什么这样做有效。 ssh支持以下语法:
ssh user @ host remote_command
在bash中,我们可以指定环境变量以在运行命令之前对其进行定义。像这样的一行:
ENV_VAR_1 ='value1'ENV_VAR_2 ='value2'bash -c'echo $ ENV_VAR_1 $ ENV_VAR_2'
这使得在运行命令之前定义变量变得容易。在这种情况下,echo是我们正在运行的命令。 echo之前的所有内容都定义了环境变量。
因此,我们将这两个功能和YarekT的答案结合起来得到:
在这种情况下,我们将ARG1和ARG2设置为本地值。在user @ host之后将所有内容作为remote_command发送。当远程计算机执行命令ARG1和ARG2时,设置了本地值,这要归功于本地命令行评估,该评估在远程服务器上定义了环境变量,然后使用这些变量执行bash -s命令。瞧,
评论
请注意,如果要传递-a这样的参数,则可以使用-。例如'ssh user @ host--a foo bar'bash -s'
–gaoithe
16 Mar 10 '16 at 17:28
如果任何env var值包含空格,请使用:ssh user @ host“ ARG1 = \” $ ARG1 \“ ARG2 = \” $ ARG2 \“”'bash -s'<<<'ENDSSH'...
–TalkLittle
16 Sep 24'4:01在
就像我在另一条评论中所写的那样,使用-s的重点是能够将参数应用于通过stdin生成的脚本。我的意思是,如果您不打算使用它,也可以忽略它。如果确实使用它,则没有理由使用环境变量:ssh user @ host'bash -s value1 value2'<<<'echo“ $ @”'
– JoL
18-09-17在21:09
#5 楼
<hostA_shell_prompt>$ ssh user@hostB "ls -la"
这将提示您输入密码,除非您已将hostA用户的公共密钥复制到用户.ssh目录的目录中的authorized_keys文件中。这将允许无密码身份验证(如果在ssh服务器的配置上被接受为身份验证方法)
评论
投票给你。这是一个有效的解决方案。显然,密钥必须受到保护,但是它们也可以像通过服务器端的密码一样失效。
–willasaywhat
08年11月21日在17:44
我认为这不能回答问题。该示例显示了如何运行远程命令,而不显示如何在远程计算机上执行本地脚本。
–Jason R. Coombs
10年4月28日在21:03
不确定,但是您不能使用此方法通过管道将hostA上的脚本运行在hostB上吗?
–nevets1219
2010-4-28在21:13
#6 楼
我已经开始使用Fabric进行更复杂的操作。 Fabric需要Python和其他几个依赖项,但仅在客户端计算机上。该服务器仅需要是ssh服务器。我发现此工具比传递给SSH的Shell脚本更强大,并且值得进行设置(特别是如果您喜欢使用Python编程)。 Fabric处理多个主机(或具有某些角色的主机)上正在运行的脚本,帮助进行幂等操作(例如,将行添加到配置脚本中,但如果已经存在则不行),并允许构造更复杂的逻辑(例如Python)语言可以提供)。#7 楼
cat ./script.sh | ssh <user>@<host>
评论
有趣的是,“ cat script.sh”的此方法| ssh user @ host'是使我在另一台主机上运行Shell脚本的唯一方法。 'bash'
–Jared Still
8月6日0:18
#8 楼
尝试运行ssh user@remote sh ./script.unx
。评论
仅当脚本位于远程服务器的默认(主)目录中时,此方法才有效。我认为问题是如何运行远程存储在本地的脚本。
– metasim
2010年7月20日在12:35
ssh username @ ip“ chmod + x script.sh”
ssh username @ ip“远程主机中sh文件的路径”
– Mani Deepak
2014年3月24日10:18
#9 楼
假设您是想从“本地”计算机上自动执行此操作,而无需手动登录“远程”计算机,则应查看一个称为Expect的TCL扩展,它是专门为这种情况而设计的。我还提供了用于通过SSH登录/交互的脚本的链接。https://www.nist.gov/services-resources/software/expect
http://bash.cyberciti.biz/security/expect-ssh-login-script/
#10 楼
我使用此脚本在远程计算机上运行shell脚本(在/ bin / bash上进行了测试):ssh deploy@host . /home/deploy/path/to/script.sh
#11 楼
ssh user@hostname ".~/.bashrc;/cd path-to-file/;.filename.sh"
强烈建议获取环境文件(.bashrc / .bashprofile / .profile)。在远程主机中运行某些命令之前,因为目标主机和源主机的环境变量可能会有所不同。
评论
这没有说明如何将本地脚本移动到远程主机。
– Kirelagin
4月16日晚上11:05
#12 楼
如果要执行这样的命令
temp=`ls -a`
echo $temp
中的命令会导致错误。
下面的命令将解决此问题
ssh user@host '''
temp=`ls -a`
echo $temp
'''
#13 楼
如果您要尝试使用plink
或ssh
在远程linux机器上运行脚本,那么这里的答案(https://stackoverflow.com/a/2732991/4752883)非常有用。它将起作用如果脚本在
linux
上有多行。**但是,如果您尝试运行位于本地
linux/windows
计算机上的批处理脚本,而您的远程计算机是Windows
,并且该脚本由使用**
多行代码
plink root@MachineB -m local_script.bat
不工作。
只执行脚本的第一行。解决方案1:
要运行多行批处理脚本(特别是如果它相对简单,则由
组成),这可能是
plink
的局限性。几行):如果原始批处理脚本如下所示
cd C:\Users\ipython_user\Desktop
python filename.py
您可以使用“ &&”分隔符将这些行组合在一起在您的
local_script.bat
文件中如下所示:https://stackoverflow.com/a/8055390/4752883:
cd C:\Users\ipython_user\Desktop && python filename.py
您可以按照
@ JasonR.Coombs此处指出的那样运行脚本:https://stackoverflow.com/a/2732991/4752883具有:
`plink root@MachineB -m local_script.bat`
解决方案2:
如果您的批处理脚本比较复杂,则最好使用批处理
脚本,该脚本封装了plink命令,并指出以下内容
@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
#14 楼
此bash脚本会将ssh SSH到目标远程计算机中,并在远程计算机中运行一些命令,在运行它之前,请不要忘记安装Expect(在Macbrew 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"
评论
如果您必须使用密码,这非常好...但是,为了让任何人在家看电视,任何ssh命令都应使用一对公钥和私钥,而不要使用密码...一旦安装到位,请更新ssh服务器以完全关闭密码
–斯科特·斯滕斯兰德
19 Mar 1 '19 at 16:25
#15 楼
chmod +x script.sh
ssh -i key-file root@111.222.3.444 < ./script.sh
#16 楼
您可以使用runoverssh: sudo apt install runoverssh
runoverssh -s localscript.sh user host1 host2 host3...
-s
远程运行本地脚本有用的标志:
-g
为所有主机使用全局密码(单个密码提示)-n
使用SSH而不是sshpass,可用于公共密钥身份验证#17 楼
如果是一个脚本,那么使用上述解决方案就可以了。我将设置Ansible来完成这项工作。它的工作方式相同(Ansible使用ssh在Unix或Windows上的远程计算机上执行脚本)。
它将更加结构化和可维护。
#18 楼
首先,使用scp将脚本复制到计算机B
[user @ machineA] $ scp / path / to / script user @ machineB:/ home / user / path
然后,只需运行脚本
[user @ machineA] $ ssh user @ machineB“ / home / user / path / script”
如果您已授予脚本可执行权限,则此方法将起作用。
评论
嗨,我应用了建议的建议,但它给了我以下错误[oracle @ node1〜] $ ssh oracle @ node2:./ home / oracle / au / fs / conn.sh ssh:node2:./ home / oracle / au / fs / conn.sh:名称或服务未知[oracle @ node1〜] $
–凯夫
08-11-20在12:47
'ssh oracle @ node2:./ home / oracle / au / fs / conn.sh'?错误的命令行,命令名称应与用户名@主机部分用空格而不是冒号分隔。
– Bortzmeyer
08年12月15日在13:37
我对此表示反对,因为它的主要主张是如果不将其复制就无法运行。
–Jason R. Coombs
10年4月28日在21:02
Jason补充说,为什么这是不正确的,而不是简单地陈述事实,这将是有帮助的。没用
–克里斯
2013年12月28日下午3:31
[user @ machineA] $ ssh root @ MachineB'bash -s' machinea / path / to / script
– Oleksii Kyslytsyn
19年6月30日在16:01
评论
同样的问题已经在serverfault上:serverfault.com/questions/215756/…因此,迁移这个问题可能没有任何意义。关于服务器故障的问题虽然没有那么多答案。也许这个问题应该取代那个问题。
我个人喜欢这个答案:unix.stackexchange.com/questions/87405/…
此外,由于ssh是软件开发的主要工具,因此显然应该成为主题。
Coffee和ssh问题对SO的异同程度不同。投票要求重新开放。