本地shell脚本中ssh到远程服务器并执行命令
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了本地shell脚本中ssh到远程服务器并执行命令相关的知识,希望对你有一定的参考价值。
参考技术A 在实际运用中在当前服务器执行命令后,需要在另一台服务器继续执行某些命令,分开去到另一台服务器执行也是比较麻烦的,因此整理下集中执行的方式1、首先配置ssh免密操作
Linux 下实现SSH互信: https://www.jianshu.com/p/2456d98aa607
2、简单命令
ssh root@192.168.1.1 "cd /var/lib; ls; cd "
2.1 使用时注意,双引号必须有。若没加双引号,第二条及之后的命令会在本地执行
2.2 分号是将两条语句间隔开
2.3 单双引的区别:单引号不会解析值,是什么就传什么;双引号会解析值,将解析结果传过去
3、多条命令
ssh root@192.168.1.1<< reallssh
cd /var/lib/test
tar -zxvf api.com.tar.gz
......
exit
reallssh
3.1 命令写在 << reallssh(开始) 至 reallssh(结束) 之间
3.2 reallssh可自己定义为其他形式
3.3 在结束前加上exit退出远程
4、可能遇到的问题
问题:远程登录主机时出现Pseudo-terminal will not be allocated because stdin is not a terminal. 错误
解决方案:字面意思是伪终端将无法分配,因为标准输入不是终端。
所以需要增加-t -t参数来强制伪终端分配,即使标准输入不是终端。
to force pseudo-tty allocation even if stdin isn’t a terminal.
参考样例如下:
ssh -t -t user1@192.168.1.1 -p 22
--------------------------------------------------------------------------------
参考:https://blog.csdn.net/jinking01/article/details/84386769
编写一个shell脚本ssh到远程机器并执行命令
【中文标题】编写一个shell脚本ssh到远程机器并执行命令【英文标题】:write a shell script to ssh to a remote machine and execute commands 【发布时间】:2012-12-05 08:56:39 【问题描述】:我有两个问题:
-
有多个远程 linux 机器,我需要编写一个 shell 脚本,在每台机器上执行相同的命令集。 (包括一些 sudo 操作)。如何使用 shell 脚本来做到这一点?
ssh到远程机器时,提示RSA指纹认证时如何处理。
远程机器是运行时创建的虚拟机,我只有它们的 IP。所以,我不能事先在这些机器中放置一个脚本文件并从我的机器上执行它们。
【问题讨论】:
我想在远程 Linux 机器上部署一个类似代理的程序,它通过网络套接字(或 SSL)连接/通过定期轮询服务器来保持与服务器的连接。 一组命令只需要执行一次,不需要维护连接 “没有脚本”的意思是“根本没有文件”,我想?您如何处理身份验证?您可以禁用主机指纹检查(请参阅我的答案),但如果您尚未设置公钥/私钥,您仍然会收到交互式密码提示。 安德烈亚斯:是的。根本没有文件。 passwd 提示可以使用expect
处理为 `expect "?assword:" `
【参考方案1】:
你可以按照这个方法:
使用 Expect Script 连接到远程计算机。如果您的机器不支持期望,您可以下载相同的。编写 Expect 脚本非常简单(谷歌可以得到帮助) 将所有需要在远程服务器上执行的操作放在一个 shell 脚本中。 登录成功后,从期望脚本调用远程 shell 脚本。【讨论】:
正如我在问题中提到的,远程机器是在运行中创建的,我不能事先在机器中放置任何脚本。 在这种情况下,将所有操作放在 Expect 脚本中。 Expect 脚本也可以在远程主机上运行命令。【参考方案2】:有多个远程 linux 机器,我需要编写一个 shell 脚本,它将在每台机器上执行相同的命令集。 (包括一些 sudo 操作)。使用 shell 脚本如何做到这一点?
你可以使用 ssh 来做到这一点,例如:
#!/bin/bash
USERNAME=someUser
HOSTS="host1 host2 host3"
SCRIPT="pwd; ls"
for HOSTNAME in $HOSTS ; do
ssh -l $USERNAME $HOSTNAME "$SCRIPT"
done
ssh到远程机器时,提示进行RSA指纹认证时如何处理。
您可以在 ssh 中添加StrictHostKeyChecking=no
选项:
ssh -o StrictHostKeyChecking=no -l username hostname "pwd; ls"
这将disable the host key check 并自动将主机密钥添加到已知主机列表中。如果您不想将主机添加到已知主机文件中,请添加选项-o UserKnownHostsFile=/dev/null
。
请注意,这会禁用某些安全检查,例如防止中间人攻击。因此,它不应该应用在安全敏感的环境中。
【讨论】:
脚本语言是什么?你当然也可以从任何 shell 脚本调用ssh
如果您还想执行 CTRL+C 并继续 ssh 到多个服务器怎么办?例如,在某些服务器中要求输入密码,而在另一些服务器中则没有,因此脚本会卡在那里。有没有一种类似于 -o 的方法来执行 CTRL c 或 CTRL d?
密码在哪里?【参考方案3】:
有很多方法可以处理这个问题。
我最喜欢的方法是在远程系统上安装http://pamsshagentauth.sourceforge.net/ 以及您自己的公钥。 (想办法把这些安装在虚拟机上,不知何故你安装了整个 Unix 系统,还有什么文件?)
转发您的 ssh 代理后,您现在无需密码即可登录每个系统。
更好的是,该 pam 模块将使用您的 ssh 密钥对对 sudo 进行身份验证,因此您可以根据需要使用 root(或任何其他用户)权限运行。
您无需担心主机密钥交互。如果输入不是终端,那么 ssh 只会限制您转发代理和使用密码进行身份验证的能力。
您还应该查看软件包 like Capistrano. 一定要环顾该网站;它介绍了远程脚本。
各个脚本行可能如下所示:
ssh remote-system-name command arguments ... # so, for exmaple,
ssh target.mycorp.net sudo puppet apply
【讨论】:
【参考方案4】:如果您能够编写 Perl 代码,那么您应该考虑使用Net::OpenSSH::Parallel。
您将能够以声明的方式描述必须在每个主机中运行的操作,并且该模块将处理所有可怕的细节。还支持通过sudo
运行命令。
【讨论】:
【参考方案5】:使用 apt-get install sshpass
安装 sshpass,然后编辑脚本并按相应顺序放置您的 linux 机器 IP、用户名和密码。之后运行该脚本。而已 !此脚本将在所有系统中安装 VLC。
#!/bin/bash
SCRIPT="cd Desktop; pwd; echo -e 'PASSWORD' | sudo -S apt-get install vlc"
HOSTS=("192.168.1.121" "192.168.1.122" "192.168.1.123")
USERNAMES=("username1" "username2" "username3")
PASSWORDS=("password1" "password2" "password3")
for i in $!HOSTS[*] ; do
echo $HOSTS[i]
SCR=$SCRIPT/PASSWORD/$PASSWORDS[i]
sshpass -p $PASSWORDS[i] ssh -l $USERNAMES[i] $HOSTS[i] "$SCR"
done
【讨论】:
使用 $SSHPASS 导出密码以避免在脚本中显示。参考:tecmint.com/…【参考方案6】:对于这类任务,我反复使用 Ansible,它允许在多个容器或 VM 中连贯地复制 bash 脚本。 Ansible(更准确地说是 Red Hat)现在有一个额外的 Web 界面 AWX,这是他们的商业 Tower 的开源版本。
Ansible:https://www.ansible.com/ AWX:https://github.com/ansible/awx Ansible Tower:商业产品,你可能会首先探索免费的开源 AWX,而不是 Tower 的 15 天免费试用
【讨论】:
【参考方案7】:这对我有用。
语法:ssh -i pemfile.pem user_name@ip_address 'command_1;命令2;命令 3'
#! /bin/bash
echo "########### connecting to server and run commands in sequence ###########"
ssh -i ~/.ssh/ec2_instance.pem ubuntu@ip_address 'touch a.txt; touch b.txt; sudo systemctl status tomcat.service'
【讨论】:
我希望在远程机器上执行一个命令,这个示例脚本在同一行的 ssh 命令之后使用远程命令提供了帮助。谢谢。【参考方案8】:有多种方法可以在多台远程 Linux 机器上执行命令或脚本。 一种简单且最简单的方法是通过 pssh(并行 ssh 程序) pssh:是一种用于在多个主机上并行执行 ssh 的程序。它提供了诸如向所有进程发送输入、向 ssh 传递密码、将输出保存到文件以及超时等功能。
示例和用法: 连接到 host1 和 host2,并分别打印“hello, world”:
pssh -i -H "host1 host2" echo "hello, world"
通过脚本在多台服务器上运行命令:
pssh -h hosts.txt -P -I<./commands.sh
在不检查或保存主机密钥的情况下使用和运行命令:
pssh -h hostname_ip.txt -x '-q -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes' -i 'uptime; hostname -f'
如果文件 hosts.txt 有大量条目,比如 100,那么也可以将并行度选项设置为 100 以确保命令同时运行:
pssh -i -h hosts.txt -p 100 -t 0 sleep 10000
选项:-I:读取输入并发送到每个 ssh 进程。 -P: 告诉 pssh 在输出到达时显示输出。 -h: 读取主机的文件。 -H : [user@]host[:port] 用于单主机。 -i: 在每个主机完成时显示标准输出和标准错误 -x args: 传递额外的 SSH 命令行参数 -o 选项: 可用于以配置文件中使用的格式给出选项。(/etc/ssh/ssh_config) (~/.ssh/config) -p 并行度: 使用给定的数量作为最大并发连接数-q 安静模式: 导致大多数警告和诊断消息被抑制。 -t: 在给定的秒数后使连接超时。 0 表示 pssh 不会使任何连接超时
ssh到远程机器时,提示输入时如何处理 RSA指纹认证。
禁用 StrictHostKeyChecking 以处理 RSA 身份验证提示。 -o StrictHostKeyChecking=no
来源:man pssh
【讨论】:
【参考方案9】:这对我有用。我做了一个函数。把它放在你的 shell 脚本中:
sshcmd()
ssh $1@$2 $3
sshcmd USER HOST COMMAND
如果您有多台机器要执行相同的命令,您可以用分号重复该行。例如,如果你有两台机器,你会这样做:
sshcmd USER HOST COMMAND ; sshcmd USER HOST COMMAND
将 USER 替换为计算机的用户。将 HOST 替换为计算机的名称。将 COMMAND 替换为您要在计算机上执行的命令。
希望这会有所帮助!
【讨论】:
【参考方案10】:接受的答案依次发送给机器。如果您想ssh
到多台机器并同时在它们上运行一些长时间运行的命令,例如scp
,请将ssh
命令作为后台进程运行。
#!/bin/bash
username="user"
servers=("srv-001" "srv-002" "srv-002" "srv-003");
script="pwd;"
for s in "$servers[@]"; do
echo "sshing $username@$s to run $script"
(ssh $username@$s $script)& # Run in background
done
wait # If removed, you can run some other script here
【讨论】:
以上是关于本地shell脚本中ssh到远程服务器并执行命令的主要内容,如果未能解决你的问题,请参考以下文章
利用shell脚本执行ssh远程另一台主机执行命令并返回命令的结果集
利用shell脚本执行ssh远程另一台主机执行命令并返回命令的结果集