当前位置: 首页 > 面试题库 >

使用Java中的JSch exec从ArrayList执行命令列表

鲍高扬
2023-03-14
问题内容

使用JSch“
exec”通道,我连接到远程服务器并执行命令。我不能执行的是存储在中的命令列表ArrayList。我使用for循环将每个元素传递给,.setCommand(elem);但是出于某种奇怪的原因,只有最后一条命令被执行。

ArrayList<String> lists = new ArrayList<String>();
lists.add("hostname");
lists.add("df -l");
Channel channel=session.openChannel("exec");

for (String elem : lists){
    ((ChannelExec)channel).setCommand(elem);
}

完整代码

public class Exec{
  public static void main(String[] arg){
    try {
      JSch jsch=new JSch();

      String host=null;
      if(arg.length>0){
        host=arg[0];
      }
      else{
        host=JOptionPane.showInputDialog("Enter username@hostname",
                                         System.getProperty("user.name")+
                                         "@localhost"); 
      }
      String user=host.substring(0, host.indexOf('@'));
      host=host.substring(host.indexOf('@')+1);

      Session session=jsch.getSession(user, host, 22);


      UserInfo ui=new MyUserInfo();
      session.setUserInfo(ui);
      session.connect();

      ArrayList<String> lists = new ArrayList<String>();
        lists.add("hostname");
        lists.add("df -l");
      Channel channel=session.openChannel("exec");

      for (String elem : lists){
          ((ChannelExec)channel).setCommand(elem);
      }

      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;
          System.out.print(new String(tmp, 0, i));
        }
        if(channel.isClosed()){
          if(in.available()>0) continue; 
          System.out.println("exit-status: "+channel.getExitStatus());
          break;
        }
        try{Thread.sleep(1000);}catch(Exception ee){}
      }
      channel.disconnect();
      session.disconnect();
    }
    catch(Exception e){
      System.out.println(e);
    }
  }

  public static class MyUserInfo implements UserInfo, UIKeyboardInteractive{
    public String getPassword(){ return passwd; }
    public boolean promptYesNo(String str){
      Object[] options={ "yes", "no" };
      int foo=JOptionPane.showOptionDialog(null, 
             str,
             "Warning", 
             JOptionPane.DEFAULT_OPTION, 
             JOptionPane.WARNING_MESSAGE,
             null, options, options[0]);
       return foo==0;
    }

    String passwd;
    JTextField passwordField=(JTextField)new JPasswordField(20);

    public String getPassphrase(){ return null; }
    public boolean promptPassphrase(String message){ return true; }
    public boolean promptPassword(String message){
      Object[] ob={passwordField}; 
      int result=
        JOptionPane.showConfirmDialog(null, ob, message,
                                      JOptionPane.OK_CANCEL_OPTION);
      if(result==JOptionPane.OK_OPTION){
        passwd=passwordField.getText();
        return true;
      }
      else{ 
        return false; 
      }
    }
    public void showMessage(String message){
      JOptionPane.showMessageDialog(null, message);
    }
    final GridBagConstraints gbc = 
      new GridBagConstraints(0,0,1,1,1,1,
                             GridBagConstraints.NORTHWEST,
                             GridBagConstraints.NONE,
                             new Insets(0,0,0,0),0,0);
    private Container panel;
    public String[] promptKeyboardInteractive(String destination,
                                              String name,
                                              String instruction,
                                              String[] prompt,
                                              boolean[] echo){
      panel = new JPanel();
      panel.setLayout(new GridBagLayout());

      gbc.weightx = 1.0;
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      gbc.gridx = 0;
      panel.add(new JLabel(instruction), gbc);
      gbc.gridy++;

      gbc.gridwidth = GridBagConstraints.RELATIVE;

      JTextField[] texts=new JTextField[prompt.length];
      for(int i=0; i<prompt.length; i++){
        gbc.fill = GridBagConstraints.NONE;
        gbc.gridx = 0;
        gbc.weightx = 1;
        panel.add(new JLabel(prompt[i]),gbc);

        gbc.gridx = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weighty = 1;
        if(echo[i]){
          texts[i]=new JTextField(20);
        }
        else{
          texts[i]=new JPasswordField(20);
        }
        panel.add(texts[i], gbc);
        gbc.gridy++;
      }

      if(JOptionPane.showConfirmDialog(null, panel, 
                                       destination+": "+name,
                                       JOptionPane.OK_CANCEL_OPTION,
                                       JOptionPane.QUESTION_MESSAGE)
         ==JOptionPane.OK_OPTION){
        String[] response=new String[prompt.length];
        for(int i=0; i<prompt.length; i++){
          response[i]=texts[i].getText();
        }
        return response;
      }
      else{
        return null;  // cancel
      }
    }
  }
}

问题答案:

您不能setCommand多次拨打。“ exec”通道只能运行一个“命令”。

但是在大多数系统/外壳上,“命令”实际上可以包括多个命令。

语法将取决于您的系统/ shell。分号通常工作:

((ChannelExec)channel).setCommand("hostname ; df -l");

一些服务器/外壳也允许换行。

((ChannelExec)channel).setCommand("hostname\ndf -l");

在* nix服务器上,还可以用于&&仅在先前命令成功执行后才执行以下命令:

((ChannelExec)channel).setCommand("hostname && df -l");

另一种选择是为每个命令打开一个新通道。请注意,您可以在一个SSH会话上拥有多个通道。您不必为每个通道/命令都重新连接。



 类似资料:
  • 通常情况下,我将执行以下操作: 然后我会得到DVD 1和DVD 2的标题。如果我想打印100个标题的DVD,显然我需要很多 我设法将这些system.out.println放在ArrayList中,如下所示: 但是,我无法执行那些system.out.println来显示标题。因此,如何执行碰巧是System.out.println命令的ArrayList的值? 非常感谢任何帮助。谢谢.

  • 问题内容: 我有一个bash脚本文件,正在shell中使用source命令调用它,并且正在设置许多环境变量。然后,我可以使用环境变量正在设置的所有工具。 现在,我想使用以下方法在Java中执行相同的操作: 我知道源是内部命令,不能从Java调用它。 还有其他方法可以通过java在该文件中设置环境变量,以便以后可以在我的代码中使用它们来调用其他命令吗? 先感谢您! 问题答案: 尝试执行类似的操作,在

  • 问题内容: 我正在尝试从用户读取一个文件,其中每一行都是一个命令,然后运行它(可以假定命令是合法的),但是当我给出类似的命令时,出现运行时异常错误: 线程“主”中的异常java.io.IOException:无法运行程序“ echo”:CreateProcess错误= 2,系统找不到指定的文件 我正在尝试运行以下命令: 在哪里。但这确实适用于类似的命令,所以看来我得到的运行时就像“运行”窗口而不是

  • 问题内容: 我正在尝试从GNU / Linux平台上的Java应用程序执行shell命令。问题是,尽管它可以从bash成功运行,但调用另一个Java应用程序的脚本永远不会结束。我试图调试它: 我尝试使用:ProcessBuilder(); 和Runtime.getRuntime()。exec(cmd); 看起来它正在等待完成。有任何想法吗? 谢谢,Laurențiu 问题答案: 您是否正在处理标准

  • 我正在使用以下代码执行一个SH文件Linux 此代码工作,但是我不能使用SH文件中的屏幕命令从Java执行时,我得到这个错误 必须连接到端子。 那么,可以将java“连接”到终端吗?当我通过SSH连接时,我想也能看到这个屏幕,所以我认为它必须连接到终端,当你通过SSH连接到服务器时,终端会显示出来。

  • 我知道有很多关于这个的线索,但是没有一个对我有用。以下是我试图做的: Javac并从我的java代码中运行一个文件。它适用于视窗系统,但我想让它也适用于UNIX。代码如下: 问题是,在UNIX系统上,它的行为“不可预测”,例如: 打开图像,但 它什么也没做。没有按摩。 我非常感谢您的任何意见。 更新--------------------------------------------------