如何使用SSH在远程计算机上运行shell脚本?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用SSH在远程计算机上运行shell脚本?相关的知识,希望对你有一定的参考价值。
我必须在远程机器上运行shell脚本(windows / Linux)。
我在机器A和B上配置了SSH。我的脚本在机器A上,它将在远程机器上运行我的一些代码,机器B.
本地和远程计算机可以是基于Windows或Unix的系统。
有没有办法使用plink / ssh运行?
如果机器A是Windows框,您可以使用Plink(PuTTY的一部分)和-m参数,它将在远程服务器上执行本地脚本。
plink root@MachineB -m local_script.sh
如果机器A是基于Unix的系统,您可以使用:
ssh root@MachineB 'bash -s' < local_script.sh
您不必将脚本复制到远程服务器以运行它。
如果你想执行命令,像这样的
temp=`ls -a`
echo $temp
命令``会导致错误。
下面的命令将解决这个问题
ssh user@host '''
temp=`ls -a`
echo $temp
'''
如果您尝试使用https://stackoverflow.com/a/2732991/4752883或plink
在远程linux机器上运行脚本,那么这里的答案(ssh
)效果很好。如果脚本在linux
上有多行,它将起作用。
**但是,如果您尝试运行位于本地linux/windows
机器上的批处理脚本,并且您的远程机器是Windows
,并且它包含多行使用**
plink root@MachineB -m local_script.bat
不会工作。
只会执行脚本的第一行。这可能是plink
的限制。
解决方案1:
要运行多行批处理脚本(特别是如果它相对简单,包含几行):
如果您的原始批处理脚本如下所示
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
这个bash脚本执行ssh到目标远程机器,并在远程机器上运行一些命令,不要忘记在运行它之前安装expect(在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"
cat ./script.sh | ssh <user>@<host>
ssh user@hostname ".~/.bashrc;/cd path-to-file/;.filename.sh"
强烈建议使用环境文件(.bashrc / .bash_profile / .profile)。在远程主机中运行之前,因为目标和源主机环境变量可能不同。
首先,使用scp将脚本复制到Machine B.
[user @ machineA] $ scp / path / to / script user @ machineB:/ home / user / path
然后,只需运行脚本
[user @ machineA] $ ssh user @ machineB“/ home / user / path / script”
如果您已授予脚本可执行权限,则此方法有效。
这是一个老问题,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
另外,如果要从目标主机中获取变量,请不要忘记转义变量。
这让我过去了。
例如:
user@host> ssh user2@host2 "echo \$HOME"
打印出/ home / user2
而
user@host> ssh user2@host2 "echo $HOME"
打印/ home / user
另一个例子:
user@host> ssh user2@host2 "echo hello world | awk 'print \$1'"
正确打印出“你好”。
这是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的答案得到:
ssh user @ host ARG1 = $ ARG1 ARG2 = $ ARG2'bash -s'<<'ENDSSH'...
在这种情况下,我们将ARG1和ARG2设置为本地值。将user @ host之后的所有内容作为remote_command发送。当远程机器执行命令时,ARG1和ARG2被设置为本地值,这要归功于在远程服务器上定义环境变量的本地命令行评估,然后使用这些变量执行bash -s命令。瞧。
<hostA_shell_prompt>$ ssh user@hostB "ls -la"
这将提示您输入密码,除非您已将hostA用户的公钥复制到用户.ssh目录主目录上的authorized_keys文件中。这将允许无密码身份验证(如果在ssh服务器的配置上被接受为auth方法)
我开始使用Fabric进行更复杂的操作。 Fabric需要Python和其他几个依赖项,但仅限于客户端计算机上。服务器只需要一个ssh服务器。我发现这个工具比传递给SSH的shell脚本更强大,值得设置的麻烦(特别是如果你喜欢用Python编程)。 Fabric处理在多个主机(或某些角色的主机)上运行脚本,有助于促进幂等操作(例如在配置脚本中添加一行,但如果它已经存在则不行),并允许构造更复杂的逻辑(例如Python)语言可以提供)。
尝试运行ssh user@remote sh ./script.unx
。
假设您想要从“本地”机器自动执行此操作,而无需手动登录“远程”机器,您应该查看名为Expect的TCL扩展,它专为此类情况而设计。我还提供了一个用于通过SSH登录/交互的脚本的链接。
https://www.nist.gov/services-resources/software/expect
http://bash.cyberciti.biz/security/expect-ssh-login-script/
我使用这个在远程机器上运行shell脚本(在/ bin / bash上测试):
ssh deploy@host . /home/deploy/path/to/script.sh
以上是关于如何使用SSH在远程计算机上运行shell脚本?的主要内容,如果未能解决你的问题,请参考以下文章