Duvida JSch: channels

7 respostas
H

Seguinte, to usando o JSch p conectar via ssh num servidor Linux e executar comandos numa app aqui.

A boa pratica nos diz p/ evitarmos sempre ta abrindo e fechando objetos q requerem mto tempo/memoria p carregar. Entao tava querendo fazer isso com o objeto ChannelExec desta biblioteca, ele serve p executar comandos e sera usados mtas vezes, por isso seria interessante so criar uma vez. Contudo, pelos testes q fiz, n to conseguindo fazer com q apenas 1 instanciacao fique executando varios comandos. So consegui executar varios comanods instanciando varias vezes o objeto Channel (ChannelExec). Queria saber se alguem ja fez isso utilizando 1 instancia dele apenas. La vai o codigo.

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

      String host=null;      
      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);
      session.setPassword("senha");
      
      // username and password will be given via UserInfo interface.
      UserInfo ui=new MyUserInfo();
      session.setUserInfo(ui);
      session.connect();

      String command=JOptionPane.showInputDialog("Enter command", 
                                                 "set|grep SSH");

      //AQUI ABRE O "CHANNELEXEC"
      Channel channel=session.openChannel("exec");
      ((ChannelExec)channel).setCommand(command);

      channel.setInputStream(null);

      ((ChannelExec)channel).setErrStream(System.err);

      InputStream in=channel.getInputStream();

      channel.connect();

      //retorna resposta do servidor
      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;
        }
        try{Thread.sleep(1000);}catch(Exception ee){}
      }
      channel.disconnect();
      session.disconnect();
    }
    catch(Exception e){
      System.out.println(e);
    }
  }

Tipo, tentei mudar o comando e dps dar connect novamente, tentei dar outros comandos como start() e run(), sem exito. So pegou dando um Channel channel=session.openChannel(“exec”); a cada novo comando.

Pelo q testei aqui, n consegui rodar varios comandos usando apenas uma instancia, ou seja, tive q abrir o channel td vez q quis executar um comando (e to c medo disso “pesar” a app). Possa ser q o modo d execucao d comandos dele seja assim msm (abrindo channel td vez) e nem pese, mas por duvida eu vim saber aqui se alguem ja conseguiu fazer isso utilizando apenas uma instancia.

7 Respostas

Aldrin_Leal

Você está usando um channel exec. Ele se responsabiliza por apenas uma única execução, o que é correto.

Se você quer executar mais um comando, você tem que usar um channel shell. Mas aí, sua lógica irá ficar mais sofisticada, porque eventualmente, você passará a interpretar as saídas do shell e não terás os códigos de retorno.

O que eu sugiro? Continue usando o exec, mas implemente um ThreadWorker. Não se preocupe em estourar recursos: Acabei de ler o fonte e ele implementa um pool, com reúso de canais fechados. Além disso, ele foi feito pra funcionar como proxy socks5 (ou seja: uma nova conexão a cada request). Logo, o protocolo foi feito pra ser abusado neste quesito.

(Em tempo: Eu realmente conferi o fonte. Em todo o caso, confira Channel.getChannel).

H

Vo dar uma olhada no codigo do shell. Mas de qlq forma, pelo q entendi, dar p continuar usando o ChannelExec msm instanciando a cada comando q ele n irá “pesar”, ne isso? Vlw…

H

Aldrin, eu olhei a execucao de comandos usando SHELL, mto bom. So achei ruin uma coisa, o retorno de alguns caracteres sai “feio” qnd tem cor, negrito, etc. Pelo q li e tentei modificar, n consegui arrumar isso, e acho q n dar, pois deve ser algo intriseco da biblioteca. Vc ja arrumou isso ou n dar?

Aldrin_Leal

Eu daria uma olhadinha na variável de ambiente TERM. O Google é o seu amigo.

H

Aldrin, abusando 1 pouco da sua ajuda, ja q vc eh um dos poucos q saca de JSch, me dar 1 help aqui.

Seguinte, to fazendo o modulo de configuracao de Rede, listar interfaces, setar ip e dhcp, visualizar mac, etc.

So q p algumas configuracoes persistirem (e n perderem qdn reinicia), eu tenho q modificar o arquivo de configs de rede em /etc.

Ai p fazer isso na aplicacao, eu vo ter q efetuar o download do arquivo no Linux p maquina cliente, editar o arquivo e so entao fazer o upload do arquivo modificado p servidor Linux. Tem alguma outra solucao mais facil?

Aldrin_Leal

commons-vfs, talvez?

H

Pelo q li aquele, ele eh 1 especie de gerenciador virtual de arquivo, bem interessante. Na sua opiniao seria melhor e mais simples usar essa api ou fazer isso atraves de JSch msm, usando os exemplos de download e upload q tem la?

Pelo q andei me aprofundando, ele n faz download do arquivo, p isso usa JSch, se n me engane…

Criado 11 de fevereiro de 2008
Ultima resposta 19 de fev. de 2008
Respostas 7
Participantes 2