背景需求:
在工作中,经常需要从本地提交节点,远程登录到其他节点上区执行一些shell命令,如果分别ssh到每台远程主机上,再去执行各个命令会很麻烦。如果可以直接在提交节点上,直接ssh到各个远程主机上去执行命令,可以省去依次登录的麻烦。
前提:
需要配置ssh免密码登录。可以直接跳过登录密码,直接登录进远程主机,这一点在shell脚本中执行时非常关键。可参见Linux下实现免密登录
例如:手工复制粘贴的方式:将本地id_rsa.pub文件的内容拷贝至远程服务器的~/.ssh/authorized_keys文件中
具体操作:
ssh远程执行命令格式:
ssh [options] [user@]host [command]
其中,host为想要连接到的远程机器名称,它是唯一的必需参数。命令ssh host登录到远程系统host,使用的用户名与正在本地系统上使用的用户名完全相同。如果希望登录的用户名与正在本地系统上使用的用户名不同,那么就应该包含user@。根据服务器设置的不同,可能还需要提供口令。
例如:
ssh simida@192.168.10.10 "cd /simida/online/data; sh update_data.sh"
注意:
- 双引号。必须将要在远程主机执行的命令,写在双引号中,否则第二个命令sh update_data.sh将在本地执行。加了双引号会让括起来的命令被当做ssh命令的一个参数,所以会在远程连续执行。
- 分号。如果多于一条命令,必须用分号隔开。
在目标服务器上执行批量的命令
如果没有提供command参数,ssh就会让你登录到host上去。远程系统显示一个shell提示符,然后就能够在host上运行命令。命令exit将会关闭与host的连接,并返回到本地系统的提示符。
#!/bin/bash
ssh simida@192.168.10.10 > /dev/null 2>&1 << remotessh #无输出日志
pwd # 远程执行
ll # 远程执行
exit
remotessh
远程执行的命令行在"< < remotessh " 至" remotessh "之间,remotessh可以随便修改成其他形式。在结束前,加exit退出远程节点。如果不想在本机输出日志,可以修改为:
#!/bin/bash
ssh simida@192.168.10.10 > /dev/null 2>&1 << remotessh #无输出日志
pwd
ll
exit
remotessh
可能遇到的问题
问题:远程登录主机时出现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)
#!/bin/bash
ssh -t -t simida@192.168.10.10 > /dev/null 2>&1 << remotessh #无输出日志
pwd
ll
exit
remotessh