shell 远程执行命令

经常需要远程到其他节点上执行一些shell命令,如果分别ssh到每台主机上再去执行很麻烦,因此能有个集中管理的方式就好了。所以介绍几种shell命令远程执行的方法。
前提条件:配置shell免密登录

 

执行单条命令

ssh user@remoteNode "df -h"

执行多条命令

ssh user@remoteNode "cd /home ; ls"  #双引号,必须有。如果不加双引号,第二个ls命令在本地执行;分号,两个命令之间用分号隔开

执行需要交互的命令

ssh user@remoteNode "sudo ls /root"
sudo: sorry, you must have a tty to run sudo
-------------------------------------------------------------------------------------------------
ssh user@remoteNode "top"
TERM environment variable not set.

这两条命令虽然提示的失败原因不同,但它们有一个共同点:都需要与用户交互(需要 TTY)。所以它们失败的原因也是相同的:
默认情况下,当你执行不带命令的 ssh 连接时,会为你分配一个 TTY。因为此时你应该是想要运行一个 shell 会话。
但是当你通过 ssh 在远程主机上执行命令时,并不会为这个远程会话分配 TTY。此时 ssh 会立即退出远程主机,所以需要交互的命令也随之结束。
好在我们可以通过 -t 参数显式的告诉 ssh,我们需要一个 TTY 远程 shell 进行交互!
添加 -t 参数后,ssh 会保持登录状态,直到你退出需要交互的命令。

ssh user@remoteNode "sudo ls /root"
sudo: sorry, you must have a tty to run sudo   #必须分配一个终端
ssh -t user@remoteNode "sudo ls /root"
[sudo] password for user:        #加-t选项后成功,输入用户密码

2.脚本方式:

2.1执行本地脚本

ssh user@remoteNode < test.sh

2.2向脚本传递参数

ssh user@remoteNode 'bash  -s' < test.sh age

2.3执行远程服务器上的脚本

ssh user@remoteNode "/tmp/test.sh"    #写脚本的绝对路径

2.4执行远程服务器上的脚本并带参数

ssh user@remoteNode "/tmp/test.sh arguement"
  • 示例2:
    初始化系统环境。在test.sh脚本中编写:关闭selinux命令、关闭iptables、修改hosts文件、安装jdk环境等。
#!/bin/bash  

#变量定义  
ip_array=("192.168.1.1" "192.168.1.2" "192.168.1.3")  
user="tester"  
remote_cmd="/home/test.sh"  


for ip in ${ip_array[@]}  
do  
    ssh -t -p $port $user@$ip "remote_cmd"  
done  

命令使用方法

ssh [-p port]  [user@]hostname [command]

port : ssh连接端口号
user: ssh连接用户名
ip:ssh连接的ip地址
cmd:远程服务器需要执行的操作
其他选项:
-t:强制分配一个伪终端,可以在远程机器上执行任何全屏幕(screen-based)程序,所以非常有用,例如菜单服务。双t选项(-tt)的意思是强制分配终端,即使ssh没有本地终端。
-T:禁止分配伪终端。
-q:静默模式,忽略所有警告和诊断信息。

### Java执行远程Shell命令的示例教程 在Java中可以通过JSch库实现SSH协议下的远程Shell命令执行。以下是详细的说明以及代码示例。 #### 使用JSch库 JSch是一个用于支持SSH协议的Java库,能够帮助开发者轻松地建立SSH连接并执行远程操作[^1]。为了使用该库,首先需要将其加入项目的依赖项中。如果是Maven项目,则可以在`pom.xml`文件中添加如下依赖: ```xml <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency> ``` #### 实现远程Shell命令执行的核心逻辑 下面展示了一个完整的例子,演示如何通过Java中的JSch库执行远程Shell命令,并捕获其返回值。 ```java import com.jcraft.jsch.*; public class RemoteShellExecutor { private static final int PORT = 22; public static void main(String[] args) { try { String host = "your.remote.server.ip"; String user = "username"; String password = "password"; String command = "ls -l"; JSch jsch = new JSch(); Session session = jsch.getSession(user, host, PORT); session.setPassword(password); // Avoid asking for key confirmation java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); System.out.println("Establishing connection..."); session.connect(); Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); // 获取输入流以便读取命令输出 InputStream in = channel.getInputStream(); channel.connect(); byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { int i = in.read(tmp, 0, 1024); if (i < 0) break; System.out.print(new String(tmp, 0, i)); } if (channel.isClosed()) { System.out.println("Exit status: " + channel.getExitStatus()); break; } Thread.sleep(1000); } channel.disconnect(); session.disconnect(); } catch (Exception e) { e.printStackTrace(); } } } ``` 上述代码展示了如何创建一个Session对象并通过它打开一个执行通道(Channel),设置待执行的命令后启动通道,并最终断开连接[^2]。 #### 处理多个Shell命令 当有多个Shell命令需要被执行时,可以根据实际需求选择不同的分隔方式。例如,使用`;`可以让所有命令按顺序依次运行而不考虑前一条命令的结果;而使用`&&`则只有当前面所有的命令均成功完成后才继续下一条命令[^3][^4]。 #### 获取远程Shell命令的返回值 除了简单的打印输出外,有时还需要处理更复杂的场景——比如根据特定条件筛选某些进程的信息或者解析日志数据等。这时可以编写专门的方法来接收这些信息并将它们转化为易于管理的形式,如列表或映射表结构[^5]。 ```java public static List<String> executeRemoteCommandsAndGetResults(String... commands) throws Exception { List<String> results = new ArrayList<>(); for (String cmd : commands){ StringBuilder outputBuffer = new StringBuilder(); JSch jsch = new JSch(); Session session = jsch.getSession("user", "host", 22); session.setPassword("pass"); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); Channel channel=session.openChannel("exec"); ((ChannelExec)channel).setCommand(cmd); InputStream in=channel.getInputStream(); channel.connect(); BufferedReader reader=new BufferedReader(new InputStreamReader(in)); String line; while((line=reader.readLine())!=null){ outputBuffer.append(line).append("\n"); } channel.disconnect(); session.disconnect(); results.add(outputBuffer.toString().trim()); } return results; } ``` 此方法接受一系列字符串形式的命令作为参数,并逐一发送给目标主机上的shell解释器去执行,最后收集各次调用所产生的标准输出内容存入List集合里供后续分析之用。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值