使用 JSch 的特定命令输出来触发下一个命令
Using specific command output of JSch to trigger next command
使用以下代码:
public static void main(String[] args) throws Exception
{
JSch jsch = new JSch();
String user = "XXXXX";
String host = "XXXXX";
String passwd = "XXXXX";
int port = 22;
Session session = jsch.getSession(user, host, port);
session.setPassword(passwd);
session.setConfig("StrictHostKeyChecking", "no");
session.setConfig("PreferredAuthentications","publickey,keyboard-interactive,password");
session.connect();
Channel channel = session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
//commands
ps.println("sudo su - user");
ps.println("ls | wc -l");
ps.println("pwd");
ps.println("exit");
ps.close();
channel.disconnect();
session.disconnect();
}
对于这种代码,是否可以:
- 分别获取在控制台上触发的每个命令的输出。
- 根据之前的输出使用控制语句。
例如:如果我使用
ls | wc -l
输出将是一个固定数字,因为根目录不会改变。使用此数字使用 if/else 条件处理步骤 a 或 b。
我不久前写了这篇文章,但我做的与您的设置方式略有不同。它抓住了 returns 你想要的一切。
编辑:我更新了代码,因此可以很容易地实用地设置用户名、主机和密码。然后循环遍历一组命令,检查 return 是否能够执行另一个命令或继续。
这是带有一些额外注释的代码(希望对您有所帮助)
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import java.io.InputStream;
import java.util.Scanner;
import java.util.Properties;
public class cmdExec
{
public static void main(String[] arg)
{
try
{
JSch jsch = new JSch();
String user = "<username>";
String host = "<host>";
String paswrd = "<password>";
Session session = jsch.getSession(user, host, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setPassword(paswrd);
session.setConfig(config);
session.connect();
// build an array of commands to run
String[] cmds = {"user | wc -l", "ps -ef | wc -l"};
for(int cnt = 0; cnt < cmds.length; cnt++)
{
String command = cmds[cnt];
Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
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;
}
// grab the return, hopefully a number
String strRet = new String(tmp, 0, i);
// trim whitespace and convert to int
int ret = Integer.parseInt(strRet.trim());
if ( ret != 1 )
{
System.out.println("Do something else, the return wasn't one.");
}
else
{
System.out.println("Return was 1. Continuing on...");
}
}
if(channel.isClosed()){
if(in.available()>0) continue;
//System.out.println("exit-status: "+channel.getExitStatus());
break;
}
try
{
Thread.sleep(1000);
}
catch (Exception ee)
{
// Do something with the exception
}
}
channel.disconnect();
}
}
catch(Exception e){
System.out.println(e);
}
}
}
使用以下代码:
public static void main(String[] args) throws Exception
{
JSch jsch = new JSch();
String user = "XXXXX";
String host = "XXXXX";
String passwd = "XXXXX";
int port = 22;
Session session = jsch.getSession(user, host, port);
session.setPassword(passwd);
session.setConfig("StrictHostKeyChecking", "no");
session.setConfig("PreferredAuthentications","publickey,keyboard-interactive,password");
session.connect();
Channel channel = session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
//commands
ps.println("sudo su - user");
ps.println("ls | wc -l");
ps.println("pwd");
ps.println("exit");
ps.close();
channel.disconnect();
session.disconnect();
}
对于这种代码,是否可以:
- 分别获取在控制台上触发的每个命令的输出。
- 根据之前的输出使用控制语句。
例如:如果我使用
ls | wc -l
输出将是一个固定数字,因为根目录不会改变。使用此数字使用 if/else 条件处理步骤 a 或 b。
我不久前写了这篇文章,但我做的与您的设置方式略有不同。它抓住了 returns 你想要的一切。
编辑:我更新了代码,因此可以很容易地实用地设置用户名、主机和密码。然后循环遍历一组命令,检查 return 是否能够执行另一个命令或继续。
这是带有一些额外注释的代码(希望对您有所帮助)
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import java.io.InputStream;
import java.util.Scanner;
import java.util.Properties;
public class cmdExec
{
public static void main(String[] arg)
{
try
{
JSch jsch = new JSch();
String user = "<username>";
String host = "<host>";
String paswrd = "<password>";
Session session = jsch.getSession(user, host, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setPassword(paswrd);
session.setConfig(config);
session.connect();
// build an array of commands to run
String[] cmds = {"user | wc -l", "ps -ef | wc -l"};
for(int cnt = 0; cnt < cmds.length; cnt++)
{
String command = cmds[cnt];
Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
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;
}
// grab the return, hopefully a number
String strRet = new String(tmp, 0, i);
// trim whitespace and convert to int
int ret = Integer.parseInt(strRet.trim());
if ( ret != 1 )
{
System.out.println("Do something else, the return wasn't one.");
}
else
{
System.out.println("Return was 1. Continuing on...");
}
}
if(channel.isClosed()){
if(in.available()>0) continue;
//System.out.println("exit-status: "+channel.getExitStatus());
break;
}
try
{
Thread.sleep(1000);
}
catch (Exception ee)
{
// Do something with the exception
}
}
channel.disconnect();
}
}
catch(Exception e){
System.out.println(e);
}
}
}