我有一个连接到SSH外壳的程序。我能够执行命令并从中读取输出。
但是我有一个新的要求。现在我需要执行一个命令并读取输出,如果成功执行下一个命令。
我用过这个问题的程序:JSch问题-无法检索完整的命令输出
public class SshConnectionManager {
private static Session session;
private static ChannelShell channel;
private static String username = "";
private static String password = "";
private static String hostname = "";
private static Session getSession(){
if(session == null || !session.isConnected()){
session = connect(hostname,username,password);
}
return session;
}
private static Channel getChannel(){
if(channel == null || !channel.isConnected()){
try{
channel = (ChannelShell)getSession().openChannel("shell");
channel.setPty(false);
channel.connect();
}catch(Exception e){
System.out.println("Error while opening channel: "+ e);
}
}
return channel;
}
private static Session connect(String hostname, String username, String password){
JSch jSch = new JSch();
try {
session = jSch.getSession(username, hostname, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(password);
System.out.println("Connecting SSH to " + hostname + " - Please wait for few seconds... ");
session.connect();
System.out.println("Connected!");
}catch(Exception e){
System.out.println("An error occurred while connecting to "+hostname+": "+e);
}
return session;
}
private static void executeCommands(List<String> commands){
try{
Channel channel=getChannel();
System.out.println("Sending commands...");
sendCommands(channel, commands);
readChannelOutput(channel);
System.out.println("Finished sending commands!");
}catch(Exception e){
System.out.println("An error ocurred during executeCommands: "+e);
}
}
private static void sendCommands(Channel channel, List<String> commands){
try{
PrintStream out = new PrintStream(channel.getOutputStream());
out.println("#!/bin/bash");
for(String command : commands){
out.println(command);
}
out.println("exit");
out.flush();
}catch(Exception e){
System.out.println("Error while sending commands: "+ e);
}
}
private static void readChannelOutput(Channel channel){
byte[] buffer = new byte[1024];
try{
InputStream in = channel.getInputStream();
String line = "";
while (true){
while (in.available() > 0) {
int i = in.read(buffer, 0, 1024);
if (i < 0) {
break;
}
line = new String(buffer, 0, i);
System.out.println(line);
}
if(line.contains("logout")){
break;
}
if (channel.isClosed()){
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee){}
}
}catch(Exception e){
System.out.println("Error while reading channel output: "+ e);
}
}
public static void close(){
channel.disconnect();
session.disconnect();
System.out.println("Disconnected channel and session");
}
public static void main(String[] args){
List<String> commands = new ArrayList<String>();
commands.add("ls -l");
executeCommands(commands);
close();
}
}
我需要使用“shell”通道而不是“exec”,因为服务器不允许“exec”通道:链接
一般来说,您应该为此使用“执行”通道。“外壳”通道不应用于自动执行命令。
但是我知道你的服务器不支持“exec”频道。我为其他读者添加了上面的评论,不要试图使用这个解决方案,除非他们真的必须这样做。
正如@Yair Harel已经评论的,如果你必须使用“shell”通道,你必须使用shell技术。
因此,在您的特定情况下,您可能希望让远程shell在命令完成后打印一些唯一的字符串和退出代码:
out.println(command + " ; echo Command-has-finished-with-code-$?");
然后你继续阅读输出,直到你找到一行开头的“命令已经完成代码-”。
分析退出代码并决定如何继续。
请注意,命令语法(特别是命令分隔符;
和退出代码变量$?
)是特定于操作系统和外壳的。由于您的服务器不是标准服务器,因此语法可能不同。
旁注:
“#!/bin/bash”
纯属无稽之谈。shell忽略所有以#
开头的命令(它是注释)。发送它没有意义StrictHostKeyChecking=no
。请参阅会话的JSch SFTP安全性。setConfig(“StrictHostKeyChecking”,“no”)我试图在unix中使用JSCHSSH类(com.jcraft.jsch)执行一些工具。我的工具有一个选择菜单。我需要转到工具所在的文件夹,执行它并选择请求的选项。在每个命令之后,(cd,execute,…)我希望检查输出并检查状态代码(0/1)。我有下面的代码按预期执行它,但在这段代码中,我找不到一种方法来检查每个命令后的输出。 我无法找到一种方法,但我怎么能分开的命令,并打印他们一个接一个(在同
为什么/我的目标: 我有一个由pi组成的小型网状网络,每天大部分时间都在运行脚本。我想取消停机时间,但是代码有时会在连续循环3-4天后停止工作,(有时长达一周,代码才会出现错误并停止)。 每个节点上运行的脚本用“最后签入”字段更新mySQL数据库。 我希望用Java编写一个小型后台程序,它将在我的服务器上无限期运行,时不时地检查每个站点的“最后签入”,如果它注意到一个节点宕机,远程ssh进入该节点
我有一个带有两个按钮的swing应用程序,用于运行和停止执行JSch命令。所以我有下一个方法,当我们点击开始按钮时调用: 正如你上面看到的,我们有is取消变量,它是布尔变量,当点击停止按钮时,我们将其设置为false。所以我的问题是当用户点击停止按钮和通道与会话成为断开,zgrep表达式继续工作在服务器上。我认为channel.disconnect()应该停止我在服务器上运行的所有命令,有人能建议
问题内容: 我想知道是否有一种方法可以在Go中运行一定的时间,然后在从通道接收到值后将其杀死。在似乎不支持命令管道。谢谢。 问题答案: 这是我的管道示例,通过OS Std Pipe归档一个调用文件b,您可以对其进行编辑并添加计时器以执行所需的操作。 文件b:
问题内容: 我想在我运行的每个bash命令之后打印日期。 这可以帮助我了解远离键盘时要执行多少命令。 我知道我能做 获取日期,但我不知道在bash上执行的每个命令之后如何甚至是否可以运行此命令。 我也会对在每个命令 之前 运行同一命令感兴趣,因此我可以知道一个命令花费了多长时间。 可能吗? 我应该编辑什么文件? 例如: 如果我也可以介绍以下功能,我将很高兴: 第一个日期是我运行程序的日期,第二个是